# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1003.9.25+1.930.107.17 -> 1.1003.9.26 # include/acpi/acglobal.h 1.22 -> 1.23 # drivers/acpi/namespace/nsxfobj.c 1.15 -> 1.16 # drivers/acpi/pci_link.c 1.1 -> (deleted) # include/asm-i386/mpspec.h 1.9 -> 1.10 # drivers/scsi/megaraid.c 1.19.1.5 -> 1.23.1.1 # include/acpi/acpixf.h 1.20 -> 1.21 # drivers/acpi/resources/rsio.c 1.11 -> 1.12 # include/linux/acpi.h 1.17 -> 1.18 # drivers/acpi/resources/rsaddr.c 1.12 -> 1.13 # drivers/acpi/power.c 1.1 -> (deleted) # drivers/acpi/executer/exoparg3.c 1.8 -> 1.9 # drivers/acpi/fan.c 1.1 -> (deleted) # include/linux/sysctl.h 1.23.1.3 -> 1.26 # drivers/acpi/hardware/hwacpi.c 1.15 -> 1.16 # drivers/acpi/debugger/dbstats.c 1.3.1.1 -> (deleted) # drivers/acpi/events/Makefile 1.2.1.1 -> 1.4 # include/acpi/acutils.h 1.22 -> 1.23 # include/acpi/acpiosxf.h 1.24 -> 1.25 # drivers/acpi/debugger/dbcmds.c 1.3.1.1 -> (deleted) # drivers/acpi/pci_root.c 1.2 -> (deleted) # drivers/acpi/dispatcher/dsobject.c 1.21 -> 1.22 # drivers/acpi/hardware/hwgpe.c 1.17 -> 1.18 # include/linux/mm.h 1.39.1.3 -> 1.46 # include/acpi/achware.h 1.15 -> 1.16 # drivers/acpi/executer/exconvrt.c 1.17 -> 1.18 # drivers/acpi/executer/exfield.c 1.15 -> 1.16 # drivers/acpi/parser/psscope.c 1.11 -> 1.12 # include/asm-i386/fixmap.h 1.4.1.2 -> 1.7 # drivers/acpi/ac.c 1.1 -> (deleted) # include/acpi/aclocal.h 1.26 -> 1.27 # drivers/acpi/tables/Makefile 1.2.1.1 -> 1.4 # include/acpi/acexcep.h 1.13 -> 1.14 # drivers/acpi/utilities/uteval.c 1.15 -> 1.16 # drivers/acpi/resources/rsutils.c 1.13 -> 1.14 # drivers/acpi/dispatcher/dswload.c 1.18 -> 1.19 # drivers/acpi/utilities/utmisc.c 1.24 -> 1.25 # drivers/acpi/hardware/hwsleep.c 1.22 -> 1.23 # drivers/acpi/events/evrgnini.c 1.16 -> 1.17 # drivers/acpi/executer/exdump.c 1.15 -> 1.16 # include/acpi/acstruct.h 1.12 -> 1.13 # kernel/sysctl.c 1.19.1.2 -> 1.21 # Makefile 1.190.1.32 -> 1.193.1.20 # drivers/acpi/events/evregion.c 1.17 -> 1.18 # drivers/acpi/dispatcher/dsfield.c 1.18 -> 1.19 # drivers/acpi/utilities/utglobal.c 1.20 -> 1.21 # include/acpi/acnamesp.h 1.17 -> 1.18 # drivers/acpi/executer/exstoren.c 1.14 -> 1.15 # include/asm-ia64/mmu_context.h 1.4.1.1 -> 1.5.2.1 # include/acpi/acobject.h 1.16 -> 1.17 # drivers/acpi/hardware/hwtimer.c 1.14 -> 1.15 # include/acpi/acresrc.h 1.12 -> 1.13 # drivers/acpi/utilities/utalloc.c 1.14 -> 1.15 # drivers/acpi/utilities/utxface.c 1.15 -> 1.16 # arch/ia64/kernel/setup.c 1.11.1.1 -> 1.11.2.1 # drivers/acpi/resources/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/executer/exregion.c 1.14 -> 1.15 # drivers/acpi/resources/rsxface.c 1.15 -> 1.16 # include/acpi/actbl1.h 1.11 -> 1.12 # drivers/acpi/system.c 1.2 -> (deleted) # drivers/acpi/namespace/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/parser/psopcode.c 1.15 -> 1.16 # include/acpi/acdebug.h 1.16 -> 1.17 # drivers/acpi/events/evxfregn.c 1.15 -> 1.16 # drivers/acpi/executer/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/parser/psparse.c 1.17 -> 1.18 # drivers/acpi/debugger/dbutils.c 1.3.1.1 -> (deleted) # include/asm-arm/page.h 1.4.1.1 -> 1.6 # init/main.c 1.26.1.1 -> 1.28 # arch/i386/kernel/Makefile 1.6 -> 1.7 # drivers/acpi/parser/pswalk.c 1.12 -> 1.13 # drivers/ide/ide-dma.c 1.6.1.6 -> 1.10.1.2 # drivers/acpi/executer/exprep.c 1.14 -> 1.15 # drivers/acpi/executer/exutils.c 1.17 -> 1.18 # drivers/acpi/executer/exoparg6.c 1.7 -> 1.8 # drivers/acpi/debugger/dbdisply.c 1.3.1.1 -> (deleted) # include/acpi/acconfig.h 1.35 -> 1.36 # drivers/acpi/dispatcher/Makefile 1.2.1.1 -> 1.4 # include/acpi/platform/acenv.h 1.12 -> 1.13 # drivers/acpi/namespace/nsxfname.c 1.14 -> 1.15 # drivers/acpi/tables/tbinstal.c 1.16 -> 1.17 # drivers/acpi/executer/exresnte.c 1.16 -> 1.17 # drivers/acpi/tables/tbutils.c 1.15 -> 1.16 # drivers/acpi/ec.c 1.1 -> (deleted) # include/linux/fs.h 1.69.1.6 -> 1.73 # drivers/scsi/Makefile 1.19 -> 1.20 # drivers/acpi/resources/rsmisc.c 1.11 -> 1.12 # drivers/acpi/resources/rsmemory.c 1.12 -> 1.13 # arch/i386/kernel/acpi.c 1.2 -> (deleted) # drivers/acpi/battery.c 1.1 -> (deleted) # drivers/acpi/debugger/dbexec.c 1.2.1.1 -> (deleted) # drivers/acpi/dispatcher/dsopcode.c 1.17 -> 1.18 # include/acpi/actables.h 1.13 -> 1.14 # drivers/acpi/osl.c 1.2 -> (deleted) # drivers/net/Makefile 1.29.1.6 -> 1.33.1.1 # drivers/acpi/events/evxfevnt.c 1.17 -> 1.18 # drivers/acpi/parser/pstree.c 1.12 -> 1.13 # drivers/acpi/parser/psargs.c 1.16 -> 1.17 # drivers/hotplug/acpiphp_glue.c 1.5 -> 1.6 # drivers/acpi/executer/exnames.c 1.12 -> 1.13 # arch/i386/kernel/mpparse.c 1.27 -> 1.28 # drivers/acpi/executer/exfldio.c 1.19 -> 1.20 # arch/i386/config.in 1.43 -> 1.44 # arch/i386/kernel/io_apic.c 1.27 -> 1.28 # drivers/acpi/acpi_ksyms.c 1.21 -> 1.22 # drivers/acpi/utilities/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/resources/rscreate.c 1.14 -> 1.15 # include/asm-ia64/processor.h 1.16.2.2 -> 1.16.2.3 # include/acpi/acoutput.h 1.14 -> 1.15 # drivers/acpi/namespace/nsinit.c 1.18 -> 1.19 # drivers/acpi/dispatcher/dsmthdat.c 1.18 -> 1.19 # drivers/acpi/namespace/nsobject.c 1.14 -> 1.15 # drivers/acpi/executer/exresolv.c 1.15 -> 1.16 # drivers/acpi/executer/excreate.c 1.14 -> 1.15 # drivers/acpi/tables/tbconvrt.c 1.21 -> 1.22 # drivers/acpi/namespace/nseval.c 1.15 -> 1.16 # arch/i386/kernel/pci-pc.c 1.24.1.4 -> 1.31 # include/linux/pci_ids.h 1.44.1.21 -> 1.46.1.14 # include/asm-i386/pci.h 1.14.1.2 -> 1.17 # drivers/net/tg3.c 1.61.2.4 -> 1.62.1.4 # drivers/acpi/utilities/utcopy.c 1.20 -> 1.21 # arch/ia64/mm/init.c 1.7.2.1 -> 1.7.3.1 # drivers/scsi/Config.in 1.15.1.4 -> 1.18.1.1 # drivers/acpi/executer/exstore.c 1.21 -> 1.22 # include/acpi/actbl71.h 1.10 -> 1.11 # drivers/acpi/resources/rsirq.c 1.12 -> 1.13 # drivers/acpi/dispatcher/dsutils.c 1.15 -> 1.16 # arch/i386/kernel/setup.c 1.68 -> 1.69 # kernel/printk.c 1.9.1.2 -> 1.13 # drivers/acpi/utilities/utdelete.c 1.16 -> 1.17 # drivers/acpi/dispatcher/dsmethod.c 1.14 -> 1.15 # arch/ia64/kernel/acpi.c 1.6.3.8 -> 1.6.4.1 # drivers/acpi/debugger/dbdisasm.c 1.3.1.1 -> (deleted) # drivers/acpi/namespace/nsutils.c 1.21 -> 1.22 # include/acpi/actbl.h 1.13 -> 1.14 # include/acpi/acpi.h 1.8 -> 1.9 # drivers/acpi/utils.c 1.1 -> (deleted) # arch/ia64/config.in 1.13.4.1 -> 1.13.4.2 # drivers/acpi/executer/exoparg2.c 1.17 -> 1.18 # drivers/acpi/namespace/nsalloc.c 1.15 -> 1.16 # drivers/acpi/resources/rscalc.c 1.15 -> 1.16 # arch/i386/kernel/acpi_wakeup.S 1.1 -> (deleted) # include/acpi/acmacros.h 1.17 -> 1.18 # drivers/acpi/parser/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/resources/rsdump.c 1.13 -> 1.14 # arch/ia64/kernel/sys_ia64.c 1.8.1.2 -> 1.9.2.1 # fs/Makefile 1.16.1.1 -> 1.18 # drivers/acpi/events/evxface.c 1.17 -> 1.18 # drivers/acpi/utilities/utinit.c 1.15 -> 1.16 # drivers/acpi/parser/psutils.c 1.11 -> 1.12 # include/acpi/actypes.h 1.27 -> 1.28 # include/acpi/acevents.h 1.16 -> 1.17 # drivers/acpi/events/evmisc.c 1.20 -> 1.21 # drivers/acpi/executer/exconfig.c 1.13 -> 1.14 # kernel/exec_domain.c 1.8.1.1 -> 1.10 # arch/ia64/hp/common/sba_iommu.c 1.1.2.11 -> 1.1.3.1 # include/acpi/actbl2.h 1.14 -> 1.15 # drivers/acpi/utilities/utdebug.c 1.16 -> 1.17 # drivers/acpi/debugger/dbhistry.c 1.2.1.1 -> (deleted) # drivers/acpi/tables/tbget.c 1.16 -> 1.17 # drivers/net/eepro100.c 1.36.2.16 -> 1.37.1.7 # include/acpi/acparser.h 1.13 -> 1.14 # drivers/acpi/utilities/utobject.c 1.16 -> 1.17 # include/acpi/amlcode.h 1.14 -> 1.15 # fs/Config.in 1.20.1.1 -> 1.23 # include/asm-i386/io_apic.h 1.10 -> 1.11 # drivers/acpi/events/evsci.c 1.14 -> 1.15 # drivers/acpi/executer/exsystem.c 1.12 -> 1.13 # drivers/acpi/debugger/dbfileio.c 1.3.1.1 -> (deleted) # drivers/acpi/bus.c 1.2 -> (deleted) # include/acpi/acdispat.h 1.11 -> 1.12 # drivers/acpi/debugger/dbxface.c 1.3.1.1 -> (deleted) # drivers/acpi/tables/tbxfroot.c 1.14 -> 1.15 # drivers/acpi/processor.c 1.1 -> (deleted) # include/acpi/platform/aclinux.h 1.17 -> 1.18 # drivers/acpi/debugger/Makefile 1.1.1.1 -> (deleted) # drivers/acpi/executer/exmutex.c 1.10 -> 1.11 # drivers/acpi/parser/psxface.c 1.14 -> 1.15 # include/asm-i386/acpi.h 1.1 -> (deleted) # include/asm-i386/save_state.h 1.1 -> (deleted) # drivers/acpi/events/evevent.c 1.23 -> 1.24 # drivers/acpi/executer/exmisc.c 1.17 -> 1.18 # drivers/acpi/hardware/hwregs.c 1.20 -> 1.21 # drivers/acpi/Config.in 1.9 -> 1.10 # drivers/acpi/dispatcher/dswstate.c 1.16 -> 1.17 # drivers/acpi/executer/exresop.c 1.16 -> 1.17 # include/acpi/acinterp.h 1.19 -> 1.20 # drivers/acpi/tables/tbxface.c 1.14 -> 1.15 # drivers/acpi/executer/exoparg1.c 1.17 -> 1.18 # drivers/acpi/namespace/nsdump.c 1.16 -> 1.17 # drivers/acpi/namespace/nsload.c 1.16 -> 1.17 # Documentation/Configure.help 1.162 -> 1.163 # drivers/acpi/hardware/Makefile 1.2.1.1 -> 1.4 # drivers/acpi/Makefile 1.16 -> 1.17 # drivers/acpi/executer/exstorob.c 1.16 -> 1.17 # drivers/acpi/utilities/utmath.c 1.7 -> 1.8 # drivers/acpi/button.c 1.1 -> (deleted) # drivers/acpi/debugger/dbinput.c 1.3.1.1 -> (deleted) # drivers/acpi/namespace/nssearch.c 1.16 -> 1.17 # drivers/acpi/namespace/nsaccess.c 1.18 -> 1.19 # drivers/scsi/scsi_ioctl.c 1.7.1.1 -> 1.10 # drivers/acpi/dispatcher/dswexec.c 1.18 -> 1.19 # include/acpi/platform/acgcc.h 1.16 -> 1.17 # fs/inode.c 1.36.1.1 -> 1.38 # drivers/acpi/dispatcher/dswscope.c 1.13 -> 1.14 # drivers/acpi/thermal.c 1.1 -> (deleted) # arch/i386/kernel/pci-irq.c 1.20 -> 1.21 # drivers/acpi/namespace/nswalk.c 1.12 -> 1.13 # drivers/acpi/tables.c 1.1 -> (deleted) # drivers/acpi/resources/rslist.c 1.11 -> 1.12 # drivers/acpi/pci_bind.c 1.1 -> (deleted) # drivers/acpi/pci_irq.c 1.1 -> (deleted) # drivers/acpi/namespace/nsnames.c 1.16 -> 1.17 # diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Wed Oct 8 09:05:46 2003 +++ b/Documentation/Configure.help Wed Oct 8 09:05:46 2003 @@ -18729,54 +18729,6 @@ The ACPI Sourceforge project may also be of interest: -ACPI Processor Enumeration Only -CONFIG_ACPI_HT_ONLY - This option enables limited ACPI support -- just enough to - enumerate processors from the ACPI Multiple APIC Description - Table (MADT). Note that ACPI supports both logical (e.g. Hyper- - Threading) and physical processors, where the MultiProcessor - Specification (MPS) table only supports physical processors. - - Full ACPI support (CONFIG_ACPI) is preferred. Use this option - only if you wish to limit ACPI's role to processor enumeration. - - In this configuration, ACPI defaults to off. It must be enabled - on the command-line with the "acpismp=force" option. - -Enable ACPI 2.0 with errata 1.3 -CONFIG_ACPI20 - Enable support for the 2.0 version of the ACPI interpreter. See the - help for ACPI for caveats and discussion. - -ACPI kernel configuration manager -CONFIG_ACPI_KERNEL_CONFIG - If you say `Y' here, Linux's ACPI support will use the - hardware-level system descriptions found on IA64 machines. - -ACPI Debug Statements -CONFIG_ACPI_DEBUG - The ACPI driver can optionally report errors with a great deal - of verbosity. Saying Y enables these statements. This will increase - your kernel size by around 50K. - -ACPI Bus Manager -CONFIG_ACPI_BUSMGR - The ACPI Bus Manager enumerates devices in the ACPI namespace, and - handles PnP messages. All ACPI devices use its services, so using - them requires saying Y here. - -ACPI System Driver -CONFIG_ACPI_SYS - This driver will enable your system to shut down using ACPI, and - dump your ACPI DSDT table using /proc/acpi/dsdt. - -ACPI Processor Driver -CONFIG_ACPI_CPU - This driver installs ACPI as the idle handler for Linux, and uses - ACPI C2 and C3 processor states to save power, on systems that - support it. - -ACPI Button CONFIG_ACPI_BUTTON This driver registers for events based on buttons, such as the power, sleep, and lid switch. In the future, a daemon will read @@ -18784,20 +18736,6 @@ down the system. Until then, you can cat it, and see output when a button is pressed. -CONFIG_ACPI_BATTERY - This driver adds support for battery information through - /proc/acpi/battery. If you have a mobile system with a battery, - say Y. - -CONFIG_ACPI_FAN - This driver adds support for ACPI fan devices, allowing user-mode - applications to perform basic fan control (on, off, status). - -CONFIG_ACPI_PROCESSOR - This driver installs ACPI as the idle handler for Linux, and uses - ACPI C2 and C3 processor states to save power, on systems that - support it. - ACPI AC Adapter CONFIG_ACPI_AC This driver adds support for the AC Adapter object, which indicates @@ -18807,65 +18745,18 @@ ACPI Embedded Controller CONFIG_ACPI_EC This driver is required on some systems for the proper operation of - the battery and thermal drivers. If you are compiling for a laptop, - say Y. + the battery and thermal drivers. If you are compiling for a + mobile system, say Y. -ACPI Control Method Battery -CONFIG_ACPI_CMBATT - This driver adds support for battery information through - /proc/acpi/battery. If you have a laptop with a battery, say Y. +CONFIG_ACPI_PROCESSOR + This driver installs ACPI as the idle handler for Linux, and uses + ACPI C2 and C3 processor states to save power, on systems that + support it. -ACPI Thermal CONFIG_ACPI_THERMAL This driver handles overheating conditions on laptops. It is HIGHLY recommended, as your laptop CPU may be damaged without it. -ACPI ASUS/Medion Laptop Extras -CONFIG_ACPI_ASUS - This driver provides support for extra features of ACPI-compatible - ASUS laptops. As some of Medion laptops are made by ASUS, it may also - support some Medion laptops (such as 9675 for example). It makes all - the extra buttons generate standard ACPI events that go through - /proc/acpi/events, and (on some models) adds support for changing the - display brightness and output, switching the LCD backlight on and off, - and most importantly, allows you to blink those fancy LEDs intended - for reporting mail and wireless status. - - All settings are changed via /proc/acpi/asus directory entries. Owner - and group for these entries can be set with asus_uid and asus_gid - parameters. - - More information and a userspace daemon for handling the extra buttons - at . - - If you have an ACPI-compatible ASUS laptop, say Y or M here. This - driver is still under development, so if your laptop is unsupported or - something works not quite as expected, please use the mailing list - available on the above page (acpi4asus-user@lists.sourceforge.net) - -ACPI Toshiba Laptop Extras -CONFIG_ACPI_TOSHIBA - This driver adds support for access to certain system settings - on "legacy free" Toshiba laptops. These laptops can be recognized by - their lack of a BIOS setup menu and APM support. - - On these machines, all system configuration is handled through the - ACPI. This driver is required for access to controls not covered - by the general ACPI drivers, such as LCD brightness, video output, - etc. - - This driver differs from the non-ACPI Toshiba laptop driver (located - under "Processor type and features") in several aspects. - Configuration is accessed by reading and writing text files in the - /proc tree instead of by program interface to /dev. Furthermore, no - power management functions are exposed, as those are handled by the - general ACPI drivers. - - More information about this driver is available at - . - - If you have a legacy free Toshiba laptop (such as the Libretto L1 - series), say Y. Advanced Power Management BIOS support CONFIG_APM @@ -25977,11 +25868,13 @@ # Choice: ia64type Itanium CONFIG_ITANIUM - Select your IA64 processor type. The default is Intel Itanium. + Select your IA-64 processor type. The default is Intel Itanium. + This choice is safe for all IA-64 systems, but may not perform + optimally on systems with, say, Itanium 2 or newer processors. -McKinley +Itanium 2 CONFIG_MCKINLEY - Select this to configure for a McKinley processor. + Select this to configure for an Itanium 2 (McKinley) processor. # Choice: ia64system IA-64 system type @@ -26058,12 +25951,31 @@ and restore instructions. It's useful for tracking down spinlock problems, but slow! If you're unsure, select N. -Early printk support (requires VGA!) +Early printk support CONFIG_IA64_EARLY_PRINTK - Selecting this option uses the VGA screen for printk() output before - the consoles are initialised. It is useful for debugging problems - early in the boot process, but only if you have a VGA screen - attached. If you're unsure, select N. + Selecting this option uses a UART or VGA screen (or both) for + printk() output before the consoles are initialised. It is useful + for debugging problems early in the boot process, but only if you + have a serial terminal or a VGA screen attached. If you're unsure, + select N. + +Early printk on serial port +CONFIG_IA64_EARLY_PRINTK_UART + Select this option to use a serial port for early printk() output. + You must also select either CONFIG_IA64_EARLY_PRINTK_UART_BASE or + CONFIG_SERIAL_HCDP. If you select CONFIG_SERIAL_HCDP, early + printk() output will appear on the first console device described by + the HCDP. If you set CONFIG_IA64_EARLY_PRINTK_UART_BASE, the HCDP + will be ignored. + +UART base address +CONFIG_IA64_EARLY_PRINTK_UART_BASE + The physical MMIO address of the UART to use for early printk(). + This overrides any UART located using the EFI HCDP table. + +Early printk on VGA +CONFIG_IA64_EARLY_PRINTK_VGA + Select this option to use VGA for early printk() output. Print possible IA64 hazards to console CONFIG_IA64_PRINT_HAZARDS diff -Nru a/Makefile b/Makefile --- a/Makefile Wed Oct 8 09:05:45 2003 +++ b/Makefile Wed Oct 8 09:05:45 2003 @@ -93,6 +93,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common +CFLAGS += -g ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -304,8 +305,7 @@ $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks - $(MAKE) -C scripts kconfig.tk - wish -f scripts/kconfig.tk + @echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***" menuconfig: include/linux/version.h symlinks $(MAKE) -C scripts/lxdialog all diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c --- a/arch/i386/kernel/acpi.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,557 +0,0 @@ -/* - * acpi.c - Architecture-Specific Low-Level ACPI Support - * - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2001 Jun Nakajima - * Copyright (C) 2001 Patrick Mochel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define PREFIX "ACPI: " - - -/* -------------------------------------------------------------------------- - Boot-time Configuration - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_BOOT - -enum acpi_irq_model_id acpi_irq_model; - - -/* - * Use reserved fixmap pages for physical-to-virtual mappings of ACPI tables. - * Note that the same range is used for each table, so tables that need to - * persist should be memcpy'd. - */ -char * -__acpi_map_table ( - unsigned long phys_addr, - unsigned long size) -{ - unsigned long base = 0; - unsigned long mapped_phys = phys_addr; - unsigned long offset = phys_addr & (PAGE_SIZE - 1); - unsigned long mapped_size = PAGE_SIZE - offset; - unsigned long avail_size = mapped_size + (PAGE_SIZE * FIX_ACPI_PAGES); - int idx = FIX_ACPI_BEGIN; - - if (!phys_addr || !size) - return NULL; - - base = fix_to_virt(FIX_ACPI_BEGIN); - - set_fixmap(idx, mapped_phys); - - if (size > avail_size) - return NULL; - - /* If the table doesn't map completely into the fist page... */ - if (size > mapped_size) { - do { - /* Make sure we don't go past our range */ - if (idx++ == FIX_ACPI_END) - return NULL; - mapped_phys = mapped_phys + PAGE_SIZE; - set_fixmap(idx, mapped_phys); - mapped_size = mapped_size + PAGE_SIZE; - } while (mapped_size < size); - } - - return ((unsigned char *) base + offset); -} - - -#ifdef CONFIG_X86_LOCAL_APIC - -int acpi_lapic; - -static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; - - -static int __init -acpi_parse_madt ( - unsigned long phys_addr, - unsigned long size) -{ - struct acpi_table_madt *madt = NULL; - - if (!phys_addr || !size) - return -EINVAL; - - madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map MADT\n"); - return -ENODEV; - } - - if (madt->lapic_address) - acpi_lapic_addr = (u64) madt->lapic_address; - - printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); - - return 0; -} - - -static int __init -acpi_parse_lapic ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic *processor = NULL; - - processor = (struct acpi_table_lapic*) header; - if (!processor) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_register_lapic ( - processor->id, /* APIC ID */ - processor->flags.enabled); /* Enabled? */ - - return 0; -} - - -static int __init -acpi_parse_lapic_addr_ovr ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; - - lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; - if (!lapic_addr_ovr) - return -EINVAL; - - acpi_lapic_addr = lapic_addr_ovr->address; - - return 0; -} - - -static int __init -acpi_parse_lapic_nmi ( - acpi_table_entry_header *header) -{ - struct acpi_table_lapic_nmi *lapic_nmi = NULL; - - lapic_nmi = (struct acpi_table_lapic_nmi*) header; - if (!lapic_nmi) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - if (lapic_nmi->lint != 1) - printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); - - return 0; -} - -#endif /*CONFIG_X86_LOCAL_APIC*/ - -#ifdef CONFIG_X86_IO_APIC - -int acpi_ioapic; - -static int __init -acpi_parse_ioapic ( - acpi_table_entry_header *header) -{ - struct acpi_table_ioapic *ioapic = NULL; - - ioapic = (struct acpi_table_ioapic*) header; - if (!ioapic) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_register_ioapic ( - ioapic->id, - ioapic->address, - ioapic->global_irq_base); - - return 0; -} - - -static int __init -acpi_parse_int_src_ovr ( - acpi_table_entry_header *header) -{ - struct acpi_table_int_src_ovr *intsrc = NULL; - - intsrc = (struct acpi_table_int_src_ovr*) header; - if (!intsrc) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - mp_override_legacy_irq ( - intsrc->bus_irq, - intsrc->flags.polarity, - intsrc->flags.trigger, - intsrc->global_irq); - - return 0; -} - - -static int __init -acpi_parse_nmi_src ( - acpi_table_entry_header *header) -{ - struct acpi_table_nmi_src *nmi_src = NULL; - - nmi_src = (struct acpi_table_nmi_src*) header; - if (!nmi_src) - return -EINVAL; - - acpi_table_print_madt_entry(header); - - /* TBD: Support nimsrc entries? */ - - return 0; -} - -#endif /*CONFIG_X86_IO_APIC*/ - - -static unsigned long __init -acpi_scan_rsdp ( - unsigned long start, - unsigned long length) -{ - unsigned long offset = 0; - unsigned long sig_len = sizeof("RSD PTR ") - 1; - - /* - * Scan all 16-byte boundaries of the physical memory region for the - * RSDP signature. - */ - for (offset = 0; offset < length; offset += 16) { - if (0 != strncmp((char *) (start + offset), "RSD PTR ", sig_len)) - continue; - return (start + offset); - } - - return 0; -} - - -unsigned long __init -acpi_find_rsdp (void) -{ - unsigned long rsdp_phys = 0; - - /* - * Scan memory looking for the RSDP signature. First search EBDA (low - * memory) paragraphs and then search upper memory (E0000-FFFFF). - */ - rsdp_phys = acpi_scan_rsdp (0, 0x400); - if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); - - return rsdp_phys; -} - - -int __init -acpi_boot_init ( - char *cmdline) -{ - int result = 0; - - /* - * The default interrupt routing model is PIC (8259). This gets - * overriden if IOAPICs are enumerated (below). - */ - acpi_irq_model = ACPI_IRQ_MODEL_PIC; - - /* - * Initialize the ACPI boot-time table parser. - */ - result = acpi_table_init(cmdline); - if (0 != result) - return result; - -#ifdef CONFIG_X86_LOCAL_APIC - - /* - * MADT - * ---- - * Parse the Multiple APIC Description Table (MADT), if exists. - * Note that this table provides platform SMP configuration - * information -- the successor to MPS tables. - */ - - result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (0 == result) { - printk(KERN_WARNING PREFIX "MADT not present\n"); - return 0; - } - else if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing MADT\n"); - return result; - } - else if (1 < result) - printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); - - /* - * Local APIC - * ---------- - * Note that the LAPIC address is obtained from the MADT (32-bit value) - * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). - */ - - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr); - if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - return result; - } - - mp_register_lapic_address(acpi_lapic_addr); - - result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic); - if (0 == result) { - printk(KERN_ERR PREFIX "No LAPIC entries present\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return -ENODEV; - } - else if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi); - if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - acpi_lapic = 1; - -#endif /*CONFIG_X86_LOCAL_APIC*/ - -#ifdef CONFIG_X86_IO_APIC - - /* - * I/O APIC - * -------- - */ - - result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic); - if (0 == result) { - printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); - return -ENODEV; - } - else if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); - return result; - } - - /* Build a default routing table for legacy (ISA) interrupts. */ - mp_config_acpi_legacy_irqs(); - - result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr); - if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); - if (0 > result) { - printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); - /* TBD: Cleanup to allow fallback to MPS */ - return result; - } - - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; - - acpi_ioapic = 1; - -#endif /*CONFIG_X86_IO_APIC*/ - -#ifdef CONFIG_X86_LOCAL_APIC - if (acpi_lapic && acpi_ioapic) - smp_found_config = 1; -#endif - - return 0; -} - -int -acpi_register_irq ( - u32 gsi, - u32 polarity, - u32 mode) -{ - return gsi; -} - -#endif /*CONFIG_ACPI_BOOT*/ - - -/* -------------------------------------------------------------------------- - Low-Level Sleep Support - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_SLEEP - -#define DEBUG - -#ifdef DEBUG -#include -#endif - -/* address in low memory of the wakeup routine. */ -unsigned long acpi_wakeup_address = 0; - -/* new page directory that we will be using */ -static pmd_t *pmd; - -/* saved page directory */ -static pmd_t saved_pmd; - -/* page which we'll use for the new page directory */ -static pte_t *ptep; - -extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); - -/* - * acpi_create_identity_pmd - * - * Create a new, identity mapped pmd. - * - * Do this by creating new page directory, and marking all the pages as R/W - * Then set it as the new Page Middle Directory. - * And, of course, flush the TLB so it takes effect. - * - * We save the address of the old one, for later restoration. - */ -static void acpi_create_identity_pmd (void) -{ - pgd_t *pgd; - int i; - - ptep = (pte_t*)__get_free_page(GFP_KERNEL); - - /* fill page with low mapping */ - for (i = 0; i < PTRS_PER_PTE; i++) - set_pte(ptep + i, mk_pte_phys(i << PAGE_SHIFT, PAGE_SHARED)); - - pgd = pgd_offset(current->active_mm, 0); - pmd = pmd_alloc(current->mm,pgd, 0); - - /* save the old pmd */ - saved_pmd = *pmd; - - /* set the new one */ - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep))); - - /* flush the TLB */ - local_flush_tlb(); -} - -/* - * acpi_restore_pmd - * - * Restore the old pmd saved by acpi_create_identity_pmd and - * free the page that said function alloc'd - */ -static void acpi_restore_pmd (void) -{ - set_pmd(pmd, saved_pmd); - local_flush_tlb(); - free_page((unsigned long)ptep); -} - -/** - * acpi_save_state_mem - save kernel state - * - * Create an identity mapped page table and copy the wakeup routine to - * low memory. - */ -int acpi_save_state_mem (void) -{ - acpi_create_identity_pmd(); - acpi_copy_wakeup_routine(acpi_wakeup_address); - - return 0; -} - -/** - * acpi_save_state_disk - save kernel state to disk - * - */ -int acpi_save_state_disk (void) -{ - return 1; -} - -/* - * acpi_restore_state - */ -void acpi_restore_state_mem (void) -{ - acpi_restore_pmd(); -} - -/** - * acpi_reserve_bootmem - do _very_ early ACPI initialisation - * - * We allocate a page in low memory for the wakeup - * routine for when we come back from a sleep state. The - * runtime allocator allows specification of <16M pages, but not - * <1M pages. - */ -void __init acpi_reserve_bootmem(void) -{ - acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); - printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); -} - -#endif /*CONFIG_ACPI_SLEEP*/ - diff -Nru a/arch/i386/kernel/acpi_wakeup.S b/arch/i386/kernel/acpi_wakeup.S --- a/arch/i386/kernel/acpi_wakeup.S Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,139 +0,0 @@ - -.text -#include -#include - - -ALIGN -wakeup_start: -wakeup_code: - wakeup_code_start = . - .code16 - - cli - cld - - # setup data segment - movw %cs, %ax - - addw $(wakeup_data - wakeup_code) >> 4, %ax - movw %ax, %ds - movw %ax, %ss - mov $(wakeup_stack - wakeup_data), %sp # Private stack is needed for ASUS board - - # set up page table - movl (real_save_cr3 - wakeup_data), %eax - movl %eax, %cr3 - - # make sure %cr4 is set correctly (features, etc) - movl (real_save_cr4 - wakeup_data), %eax - movl %eax, %cr4 - - # need a gdt - lgdt real_save_gdt - wakeup_data - - movl %cr0, %eax - orl $0x80000001, %eax - movl %eax, %cr0 - - ljmpl $__KERNEL_CS,$SYMBOL_NAME(wakeup_pmode_return) - - .code32 - ALIGN - -.org 0x100 -wakeup_data: - .word 0 -real_save_gdt: .word 0 - .long 0 -real_save_cr3: .long 0 -real_save_cr4: .long 0 - -.org 0x300 -wakeup_stack: -wakeup_end: - -wakeup_pmode_return: - # restore data segment - movl $__KERNEL_DS, %eax - movw %ax, %ds - movw %ax, %es - - # and restore the stack - movw %ax, %ss - movl saved_esp, %esp - - # restore other segment registers - xorl %eax, %eax - movw %ax, %fs - movw %ax, %gs - - # reload the gdt, as we need the full 32 bit address - lgdt saved_gdt - lidt saved_idt - lldt saved_ldt - - # restore the other general registers - movl saved_ebx, %ebx - movl saved_edi, %edi - movl saved_esi, %esi - movl saved_ebp, %ebp - - # jump to place where we left off - movl saved_eip,%eax - jmp *%eax - -## -# acpi_copy_wakeup_routine -# -# Copy the above routine to low memory. -# -# Parameters: -# %eax: place to copy wakeup routine to -# -# Returned address is location of code in low memory (past data and stack) -# -ENTRY(acpi_copy_wakeup_routine) - - pushl %esi - pushl %edi - - sgdt saved_gdt - sidt saved_idt - sldt saved_ldt - str saved_tss - - movl %eax, %edi - leal wakeup_start, %esi - movl $(wakeup_end - wakeup_start) >> 2, %ecx - - rep ; movsl - - movl %cr3, %edx - movl %edx, real_save_cr3 - wakeup_start (%eax) - movl %cr4, %edx - movl %edx, real_save_cr4 - wakeup_start (%eax) - sgdt real_save_gdt - wakeup_start (%eax) - - # restore the regs we used - popl %edi - popl %esi - ret - - -.data -ALIGN -# saved registers -saved_gdt: .long 0,0 -saved_idt: .long 0,0 -saved_ldt: .long 0 -saved_tss: .long 0 -saved_cr0: .long 0 - -ENTRY(saved_ebp) .long 0 -ENTRY(saved_esi) .long 0 -ENTRY(saved_edi) .long 0 -ENTRY(saved_ebx) .long 0 - -ENTRY(saved_eip) .long 0 -ENTRY(saved_esp) .long 0 diff -Nru a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c --- a/arch/i386/kernel/pci-pc.c Wed Oct 8 09:05:45 2003 +++ b/arch/i386/kernel/pci-pc.c Wed Oct 8 09:05:45 2003 @@ -29,6 +29,8 @@ int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; +static int pci_using_acpi_prt = 0; + #ifdef CONFIG_MULTIQUAD #define BUS2QUAD(global) (mp_bus_id_to_node[global]) #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) @@ -39,8 +41,6 @@ #define QUADLOCAL2BUS(quad,local) (local) #endif -static int pci_using_acpi_prt = 0; - /* * This interrupt-safe spinlock protects all accesses to PCI * configuration space. @@ -1414,6 +1414,8 @@ return; } +int use_acpi_pci __initdata = 1; + void __init pcibios_init(void) { int quad; @@ -1425,25 +1427,28 @@ return; } + printk(KERN_INFO "PCI: Probing PCI hardware\n"); #ifdef CONFIG_ACPI_PCI - if (acpi_pci_irq_init() > 0) + if (use_acpi_pci && !acpi_pci_irq_init()) { pci_using_acpi_prt = 1; + printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); + printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n"); + } #endif if (!pci_using_acpi_prt) { - pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL); - if (clustered_apic_mode && (numnodes > 1)) { - for (quad = 1; quad < numnodes; ++quad) { - printk("Scanning PCI bus %d for quad %d\n", - QUADLOCAL2BUS(quad,0), quad); - pci_scan_bus(QUADLOCAL2BUS(quad,0), - pci_root_ops, NULL); - } - } - + pci_root_bus = pcibios_scan_root(0); pcibios_irq_init(); pcibios_fixup_peer_bridges(); pcibios_fixup_irqs(); } + if (clustered_apic_mode && (numnodes > 1)) { + for (quad = 1; quad < numnodes; ++quad) { + printk("Scanning PCI bus %d for quad %d\n", + QUADLOCAL2BUS(quad,0), quad); + pci_scan_bus(QUADLOCAL2BUS(quad,0), + pci_root_ops, NULL); + } + } pcibios_resource_survey(); @@ -1495,6 +1500,9 @@ return NULL; } else if (!strncmp(str, "lastbus=", 8)) { pcibios_last_bus = simple_strtol(str+8, NULL, 0); + return NULL; + } else if (!strncmp(str, "noacpi", 6)) { + use_acpi_pci = 0; return NULL; } return str; diff -Nru a/arch/ia64/config.in b/arch/ia64/config.in --- a/arch/ia64/config.in Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/config.in Wed Oct 8 09:05:45 2003 @@ -86,6 +86,32 @@ define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. +define_int CONFIG_FORCE_MAX_ZONEORDER 19 + +bool 'IA-64 Huge TLB Page Support' CONFIG_HUGETLB_PAGE + +if [ "$CONFIG_HUGETLB_PAGE" = "y" ]; then + if [ "$CONFIG_MCKINLEY" = "y" ]; then + choice ' IA-64 Huge TLB Page Size' \ + "4GB CONFIG_HUGETLB_PAGE_SIZE_4GB \ + 1GB CONFIG_HUGETLB_PAGE_SIZE_1GB \ + 256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + else + choice ' IA-64 Huge TLB Page Size' \ + "256MB CONFIG_HUGETLB_PAGE_SIZE_256MB \ + 64MB CONFIG_HUGETLB_PAGE_SIZE_64MB \ + 16MB CONFIG_HUGETLB_PAGE_SIZE_16MB \ + 4MB CONFIG_HUGETLB_PAGE_SIZE_4MB \ + 1MB CONFIG_HUGETLB_PAGE_SIZE_1MB \ + 256KB CONFIG_HUGETLB_PAGE_SIZE_256KB" 16MB + fi +fi + bool 'SMP support' CONFIG_SMP tristate 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT bool 'Performance monitor support' CONFIG_PERFMON diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/hp/common/sba_iommu.c Wed Oct 8 09:05:45 2003 @@ -133,6 +133,7 @@ #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1636,6 +1637,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { REO_IOC_ID, "REO" }, + { SX1000_IOC_ID, "sx1000" }, }; static struct ioc * __init diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/kernel/acpi.c Wed Oct 8 09:05:45 2003 @@ -631,4 +631,21 @@ return gsi_to_vector(irq); } +int +acpi_register_irq (u32 gsi, u32 polarity, u32 mode) +{ + int vector = 0; + + if (has_8259 && gsi < 16) + return isa_irq_to_vector(gsi); + + if (!iosapic_register_intr) + return 0; + + /* Turn it on */ + vector = iosapic_register_intr(gsi, polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, + mode ? IOSAPIC_EDGE : IOSAPIC_LEVEL); + return vector; +} + #endif /* CONFIG_ACPI_BOOT */ diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/kernel/setup.c Wed Oct 8 09:05:45 2003 @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM # include @@ -58,6 +59,7 @@ struct cpuinfo_ia64 *boot_cpu_data; #else struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section"))); + mmu_gather_t mmu_gathers[NR_CPUS]; #endif unsigned long ia64_cycles_per_usec; @@ -567,6 +569,8 @@ for (cpu = 1; cpu < NR_CPUS; ++cpu) memcpy(my_cpu_data->cpu_data[cpu]->cpu_data, my_cpu_data->cpu_data, sizeof(my_cpu_data->cpu_data)); + my_cpu_data->mmu_gathers = alloc_bootmem_pages_node(BOOT_NODE_DATA(boot_get_local_cnodeid()), + sizeof(mmu_gather_t)); } else { order = get_order(sizeof(struct cpuinfo_ia64)); my_cpu_data = page_address(alloc_pages_node(numa_node_id(), GFP_KERNEL, order)); @@ -576,9 +580,14 @@ order); for (cpu = 0; cpu < NR_CPUS; ++cpu) boot_cpu_data->cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data; + + my_cpu_data->mmu_gathers = page_address(boot_alloc_pages_node(boot_get_local_cnodeid(), + GFP_KERNEL, + get_order(sizeof(mmu_gather_t))); } #else my_cpu_data = cpu_data(smp_processor_id()); + my_cpu_data->mmu_gathers = &mmu_gathers[smp_processor_id()]; #endif /* diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c --- a/arch/ia64/kernel/sys_ia64.c Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/kernel/sys_ia64.c Wed Oct 8 09:05:45 2003 @@ -61,16 +61,14 @@ } asmlinkage long -ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6, - long arg7, long stack) +ia64_getpriority (int which, int who) { - struct pt_regs *regs = (struct pt_regs *) &stack; extern long sys_getpriority (int, int); long prio; prio = sys_getpriority(which, who); if (prio >= 0) { - regs->r8 = 0; /* ensure negative priority is not mistaken as error code */ + force_successful_syscall_return(); prio = 20 - prio; } return prio; @@ -84,11 +82,9 @@ } asmlinkage unsigned long -ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6, - long arg7, long stack) +ia64_shmat (int shmid, void *shmaddr, int shmflg) { extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr); - struct pt_regs *regs = (struct pt_regs *) &stack; unsigned long raddr; int retval; @@ -96,16 +92,14 @@ if (retval < 0) return retval; - regs->r8 = 0; /* ensure negative addresses are not mistaken as an error code */ + force_successful_syscall_return(); return raddr; } asmlinkage unsigned long -ia64_brk (unsigned long brk, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6, long arg7, long stack) +ia64_brk (unsigned long brk) { extern int vm_enough_memory (long pages); - struct pt_regs *regs = (struct pt_regs *) &stack; unsigned long rlim, retval, newbrk, oldbrk; struct mm_struct *mm = current->mm; @@ -155,7 +149,7 @@ out: retval = mm->brk; up_write(&mm->mmap_sem); - regs->r8 = 0; /* ensure large retval isn't mistaken as error code */ + force_successful_syscall_return(); return retval; } @@ -232,29 +226,23 @@ * of) files that are larger than the address space of the CPU. */ asmlinkage unsigned long -sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff, - long arg6, long arg7, long stack) +sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff) { - struct pt_regs *regs = (struct pt_regs *) &stack; - addr = do_mmap2(addr, len, prot, flags, fd, pgoff); if (!IS_ERR((void *) addr)) - regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ + force_successful_syscall_return(); return addr; } asmlinkage unsigned long -sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, - int fd, long off, long arg6, long arg7, long stack) +sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off) { - struct pt_regs *regs = (struct pt_regs *) &stack; - if ((off & ~PAGE_MASK) != 0) return -EINVAL; addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); if (!IS_ERR((void *) addr)) - regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */ + force_successful_syscall_return(); return addr; } diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Wed Oct 8 09:05:45 2003 +++ b/arch/ia64/mm/init.c Wed Oct 8 09:05:45 2003 @@ -252,7 +252,7 @@ pte_t *pte; if (!PageReserved(page)) - printk("put_gate_page: gate page at 0x%p not in reserved memory\n", + printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n", page_address(page)); pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */ @@ -557,7 +557,7 @@ efi_memmap_walk(create_mem_map_page_table, 0); free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size); - printk("Virtual mem_map starts at 0x%p\n", mem_map); + printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map); } #endif } diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c --- a/drivers/acpi/ac.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,352 +0,0 @@ -/* - * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 23 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_AC_COMPONENT -ACPI_MODULE_NAME ("acpi_ac") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - - -int acpi_ac_add (struct acpi_device *device); -int acpi_ac_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_ac_driver = { - name: ACPI_AC_DRIVER_NAME, - class: ACPI_AC_CLASS, - ids: ACPI_AC_HID, - ops: { - add: acpi_ac_add, - remove: acpi_ac_remove, - }, -}; - -struct acpi_ac { - acpi_handle handle; - unsigned long state; -}; - - -/* -------------------------------------------------------------------------- - AC Adapter Management - -------------------------------------------------------------------------- */ - -static int -acpi_ac_get_state ( - struct acpi_ac *ac) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_ac_get_state"); - - if (!ac) - return_VALUE(-EINVAL); - - status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading AC Adapter state\n")); - ac->state = ACPI_AC_STATUS_UNKNOWN; - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_ac_dir = NULL; - -static int -acpi_ac_read_state ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_ac *ac = (struct acpi_ac *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_ac_read_state"); - - if (!ac || (off != 0)) - goto end; - - if (0 != acpi_ac_get_state(ac)) { - p += sprintf(p, "ERROR: Unable to read AC Adapter state\n"); - goto end; - } - - p += sprintf(p, "state: "); - switch (ac->state) { - case ACPI_AC_STATUS_OFFLINE: - p += sprintf(p, "off-line\n"); - break; - case ACPI_AC_STATUS_ONLINE: - p += sprintf(p, "on-line\n"); - break; - default: - p += sprintf(p, "unknown\n"); - break; - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_ac_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_ac_add_fs"); - - if (!acpi_ac_dir) { - acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); - if (!acpi_ac_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_ac_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'state' [R] */ - entry = create_proc_entry(ACPI_AC_FILE_STATE, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_AC_FILE_STATE)); - else { - entry->read_proc = acpi_ac_read_state; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_ac_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_ac_remove_fs"); - - if (!acpi_ac_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Model - -------------------------------------------------------------------------- */ - -void -acpi_ac_notify ( - acpi_handle handle, - u32 event, - void *data) -{ - struct acpi_ac *ac = (struct acpi_ac *) data; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_ac_notify"); - - if (!ac) - return; - - if (0 != acpi_bus_get_device(ac->handle, &device)) - return_VOID; - - switch (event) { - case ACPI_AC_NOTIFY_STATUS: - acpi_ac_get_state(ac); - acpi_bus_generate_event(device, event, (u32) ac->state); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return_VOID; -} - - -int -acpi_ac_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_ac *ac = NULL; - - ACPI_FUNCTION_TRACE("acpi_ac_add"); - - if (!device) - return_VALUE(-EINVAL); - - ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); - if (!ac) - return_VALUE(-ENOMEM); - memset(ac, 0, sizeof(struct acpi_ac)); - - ac->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_AC_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_AC_CLASS); - acpi_driver_data(device) = ac; - - result = acpi_ac_get_state(ac); - if (0 != result) - goto end; - - result = acpi_ac_add_fs(device); - if (0 != result) - goto end; - - status = acpi_install_notify_handler(ac->handle, - ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); - result = -ENODEV; - goto end; - } - - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), - ac->state?"on-line":"off-line"); - -end: - if (0 != result) { - acpi_ac_remove_fs(device); - kfree(ac); - } - - return_VALUE(result); -} - - -int -acpi_ac_remove ( - struct acpi_device *device, - int type) -{ - acpi_status status = AE_OK; - struct acpi_ac *ac = NULL; - - ACPI_FUNCTION_TRACE("acpi_ac_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - ac = (struct acpi_ac *) acpi_driver_data(device); - - status = acpi_remove_notify_handler(ac->handle, - ACPI_DEVICE_NOTIFY, acpi_ac_notify); - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - - acpi_ac_remove_fs(device); - - kfree(ac); - - return_VALUE(0); -} - - -int __init -acpi_ac_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_ac_init"); - - result = acpi_bus_register_driver(&acpi_ac_driver); - if (0 > result) { - remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -void __exit -acpi_ac_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_ac_exit"); - - result = acpi_bus_unregister_driver(&acpi_ac_driver); - if (0 == result) - remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); - - return_VOID; -} - - -module_init(acpi_ac_init); -module_exit(acpi_ac_exit); diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c --- a/drivers/acpi/battery.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,831 +0,0 @@ -/* - * acpi_battery.c - ACPI Battery Driver ($Revision: 32 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_BATTERY_COMPONENT -ACPI_MODULE_NAME ("acpi_battery") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - - -#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF - -#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" -#define ACPI_BATTERY_FORMAT_BST "NNNN" - -static int acpi_battery_add (struct acpi_device *device); -static int acpi_battery_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_battery_driver = { - name: ACPI_BATTERY_DRIVER_NAME, - class: ACPI_BATTERY_CLASS, - ids: ACPI_BATTERY_HID, - ops: { - add: acpi_battery_add, - remove: acpi_battery_remove, - }, -}; - -struct acpi_battery_status { - acpi_integer state; - acpi_integer present_rate; - acpi_integer remaining_capacity; - acpi_integer present_voltage; -}; - -struct acpi_battery_info { - acpi_integer power_unit; - acpi_integer design_capacity; - acpi_integer last_full_capacity; - acpi_integer battery_technology; - acpi_integer design_voltage; - acpi_integer design_capacity_warning; - acpi_integer design_capacity_low; - acpi_integer battery_capacity_granularity_1; - acpi_integer battery_capacity_granularity_2; - acpi_string model_number; - acpi_string serial_number; - acpi_string battery_type; - acpi_string oem_info; -}; - -struct acpi_battery_flags { - u8 present:1; /* Bay occupied? */ - u8 power_unit:1; /* 0=watts, 1=apms */ - u8 alarm:1; /* _BTP present? */ - u8 reserved:5; -}; - -struct acpi_battery_trips { - unsigned long warning; - unsigned long low; -}; - -struct acpi_battery { - acpi_handle handle; - struct acpi_battery_flags flags; - struct acpi_battery_trips trips; - unsigned long alarm; - struct acpi_battery_info *info; -}; - - -/* -------------------------------------------------------------------------- - Battery Management - -------------------------------------------------------------------------- */ - -static int -acpi_battery_get_info ( - struct acpi_battery *battery, - struct acpi_battery_info **bif) -{ - int result = 0; - acpi_status status = 0; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BIF), - ACPI_BATTERY_FORMAT_BIF}; - acpi_buffer data = {0, NULL}; - acpi_object *package = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_get_info"); - - if (!battery || !bif) - return_VALUE(-EINVAL); - - /* Evalute _BIF */ - - status = acpi_evaluate_object(battery->handle, "_BIF", NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BIF\n")); - return_VALUE(-ENODEV); - } - - package = (acpi_object *) buffer.pointer; - - /* Extract Package Data */ - - status = acpi_extract_package(package, &format, &data); - if (status != AE_BUFFER_OVERFLOW) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n")); - result = -ENODEV; - goto end; - } - - data.pointer = kmalloc(data.length, GFP_KERNEL); - if (!data.pointer) { - result = -ENOMEM; - goto end; - } - memset(data.pointer, 0, data.length); - - status = acpi_extract_package(package, &format, &data); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BIF\n")); - kfree(data.pointer); - result = -ENODEV; - goto end; - } - -end: - kfree(buffer.pointer); - - if (0 == result) - (*bif) = (struct acpi_battery_info *) data.pointer; - - return_VALUE(result); -} - -static int -acpi_battery_get_status ( - struct acpi_battery *battery, - struct acpi_battery_status **bst) -{ - int result = 0; - acpi_status status = 0; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_buffer format = {sizeof(ACPI_BATTERY_FORMAT_BST), - ACPI_BATTERY_FORMAT_BST}; - acpi_buffer data = {0, NULL}; - acpi_object *package = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_get_status"); - - if (!battery || !bst) - return_VALUE(-EINVAL); - - /* Evalute _BST */ - - status = acpi_evaluate_object(battery->handle, "_BST", NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BST\n")); - return_VALUE(-ENODEV); - } - - package = (acpi_object *) buffer.pointer; - - /* Extract Package Data */ - - status = acpi_extract_package(package, &format, &data); - if (status != AE_BUFFER_OVERFLOW) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n")); - result = -ENODEV; - goto end; - } - - data.pointer = kmalloc(data.length, GFP_KERNEL); - if (!data.pointer) { - result = -ENOMEM; - goto end; - } - memset(data.pointer, 0, data.length); - - status = acpi_extract_package(package, &format, &data); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n")); - kfree(data.pointer); - result = -ENODEV; - goto end; - } - -end: - kfree(buffer.pointer); - - if (0 == result) - (*bst) = (struct acpi_battery_status *) data.pointer; - - return_VALUE(result); -} - - -static int -acpi_battery_set_alarm ( - struct acpi_battery *battery, - unsigned long alarm) -{ - acpi_status status = 0; - acpi_object arg0 = {ACPI_TYPE_INTEGER}; - acpi_object_list arg_list = {1, &arg0}; - - ACPI_FUNCTION_TRACE("acpi_battery_set_alarm"); - - if (!battery) - return_VALUE(-EINVAL); - - if (!battery->flags.alarm) - return_VALUE(-ENODEV); - - arg0.integer.value = alarm; - - status = acpi_evaluate(battery->handle, "_BTP", &arg_list, NULL); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); - - battery->alarm = alarm; - - return_VALUE(0); -} - - -static int -acpi_battery_check ( - struct acpi_battery *battery) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_handle handle = NULL; - struct acpi_device *device = NULL; - struct acpi_battery_info *bif = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_check"); - - if (!battery) - return_VALUE(-EINVAL); - - result = acpi_bus_get_device(battery->handle, &device); - if (0 != result) - return_VALUE(result); - - result = acpi_bus_get_status(device); - if (0 != result) - return_VALUE(result); - - /* Insertion? */ - - if (!battery->flags.present && device->status.battery_present) { - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); - - /* Evalute _BIF to get certain static information */ - - result = acpi_battery_get_info(battery, &bif); - if (0 != result) - return_VALUE(result); - - battery->flags.power_unit = bif->power_unit; - battery->trips.warning = bif->design_capacity_warning; - battery->trips.low = bif->design_capacity_low; - kfree(bif); - - /* See if alarms are supported, and if so, set default */ - - status = acpi_get_handle(battery->handle, "_BTP", &handle); - if (ACPI_SUCCESS(status)) { - battery->flags.alarm = 1; - acpi_battery_set_alarm(battery, battery->trips.warning); - } - } - - /* Removal? */ - - else if (battery->flags.present && !device->status.battery_present) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); - } - - battery->flags.present = device->status.battery_present; - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_battery_dir = NULL; - -static int -acpi_battery_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - int result = 0; - struct acpi_battery *battery = (struct acpi_battery *) data; - struct acpi_battery_info *bif = NULL; - char *units = "?"; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_battery_read_info"); - - if (!battery) - goto end; - - if (battery->flags.present) - p += sprintf(p, "present: yes\n"); - else { - p += sprintf(p, "present: no\n"); - goto end; - } - - /* Battery Info (_BIF) */ - - result = acpi_battery_get_info(battery, &bif); - if ((0 != result) || !bif) { - p += sprintf(p, "ERROR: Unable to read battery information\n"); - goto end; - } - - units = bif->power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; - - if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "design capacity: unknown\n"); - else - p += sprintf(p, "design capacity: %d %sh\n", - (u32) bif->design_capacity, units); - - if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "last full capacity: unknown\n"); - else - p += sprintf(p, "last full capacity: %d %sh\n", - (u32) bif->last_full_capacity, units); - - switch ((u32) bif->battery_technology) { - case 0: - p += sprintf(p, "battery technology: non-rechargeable\n"); - break; - case 1: - p += sprintf(p, "battery technology: rechargeable\n"); - break; - default: - p += sprintf(p, "battery technology: unknown\n"); - break; - } - - if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "design voltage: unknown\n"); - else - p += sprintf(p, "design voltage: %d mV\n", - (u32) bif->design_voltage); - - p += sprintf(p, "design capacity warning: %d %sh\n", - (u32) bif->design_capacity_warning, units); - p += sprintf(p, "design capacity low: %d %sh\n", - (u32) bif->design_capacity_low, units); - p += sprintf(p, "capacity granularity 1: %d %sh\n", - (u32) bif->battery_capacity_granularity_1, units); - p += sprintf(p, "capacity granularity 2: %d %sh\n", - (u32) bif->battery_capacity_granularity_2, units); - p += sprintf(p, "model number: %s\n", - bif->model_number); - p += sprintf(p, "serial number: %s\n", - bif->serial_number); - p += sprintf(p, "battery type: %s\n", - bif->battery_type); - p += sprintf(p, "OEM info: %s\n", - bif->oem_info); - -end: - kfree(bif); - - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_battery_read_state ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - int result = 0; - struct acpi_battery *battery = (struct acpi_battery *) data; - struct acpi_battery_status *bst = NULL; - char *units = "?"; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_battery_read_state"); - - if (!battery) - goto end; - - if (battery->flags.present) - p += sprintf(p, "present: yes\n"); - else { - p += sprintf(p, "present: no\n"); - goto end; - } - - /* Battery Units */ - - units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; - - /* Battery Status (_BST) */ - - result = acpi_battery_get_status(battery, &bst); - if ((0 != result) || !bst) { - p += sprintf(p, "ERROR: Unable to read battery status\n"); - goto end; - } - - if (!(bst->state & 0x04)) - p += sprintf(p, "capacity state: ok\n"); - else - p += sprintf(p, "capacity state: critical\n"); - - if ((bst->state & 0x01) && (bst->state & 0x02)) - p += sprintf(p, "charging state: charging/discharging\n"); - else if (bst->state & 0x01) - p += sprintf(p, "charging state: discharging\n"); - else if (bst->state & 0x02) - p += sprintf(p, "charging state: charging\n"); - else - p += sprintf(p, "charging state: unknown\n"); - - if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "present rate: unknown\n"); - else - p += sprintf(p, "present rate: %d %s\n", - (u32) bst->present_rate, units); - - if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "remaining capacity: unknown\n"); - else - p += sprintf(p, "remaining capacity: %d %sh\n", - (u32) bst->remaining_capacity, units); - - if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) - p += sprintf(p, "present voltage: unknown\n"); - else - p += sprintf(p, "present voltage: %d mV\n", - (u32) bst->present_voltage); - -end: - kfree(bst); - - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_battery_read_alarm ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_battery *battery = (struct acpi_battery *) data; - char *units = "?"; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_battery_read_alarm"); - - if (!battery) - goto end; - - if (!battery->flags.present) { - p += sprintf(p, "present: no\n"); - goto end; - } - - /* Battery Units */ - - units = battery->flags.power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; - - /* Battery Alarm */ - - p += sprintf(p, "alarm: "); - if (!battery->alarm) - p += sprintf(p, "unsupported\n"); - else - p += sprintf(p, "%d %sh\n", (u32) battery->alarm, units); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_battery_write_alarm ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_battery *battery = (struct acpi_battery *) data; - char alarm_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_battery_write_alarm"); - - if (!battery || (count > sizeof(alarm_string) - 1)) - return_VALUE(-EINVAL); - - if (!battery->flags.present) - return_VALUE(-ENODEV); - - if (copy_from_user(alarm_string, buffer, count)) - return_VALUE(-EFAULT); - - alarm_string[count] = '\0'; - - result = acpi_battery_set_alarm(battery, - simple_strtoul(alarm_string, NULL, 0)); - if (0 != result) - return_VALUE(result); - - return_VALUE(count); -} - - -static int -acpi_battery_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_add_fs"); - - if (!acpi_battery_dir) { - acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); - if (!acpi_battery_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_battery_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'info' [R] */ - entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_BATTERY_FILE_INFO)); - else { - entry->read_proc = acpi_battery_read_info; - entry->data = acpi_driver_data(device); - } - - /* 'status' [R] */ - entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_BATTERY_FILE_STATUS)); - else { - entry->read_proc = acpi_battery_read_state; - entry->data = acpi_driver_data(device); - } - - /* 'alarm' [R/W] */ - entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_BATTERY_FILE_ALARM)); - else { - entry->read_proc = acpi_battery_read_alarm; - entry->write_proc = acpi_battery_write_alarm; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_battery_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_battery_remove_fs"); - - if (!acpi_battery_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static void -acpi_battery_notify ( - acpi_handle handle, - u32 event, - void *data) -{ - struct acpi_battery *battery = (struct acpi_battery *) data; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_notify"); - - if (!battery) - return_VOID; - - if (0 != acpi_bus_get_device(handle, &device)) - return_VOID; - - switch (event) { - case ACPI_BATTERY_NOTIFY_STATUS: - case ACPI_BATTERY_NOTIFY_INFO: - acpi_battery_check(battery); - acpi_bus_generate_event(device, event, battery->flags.present); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return_VOID; -} - - -static int -acpi_battery_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = 0; - struct acpi_battery *battery = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_add"); - - if (!device) - return_VALUE(-EINVAL); - - battery = kmalloc(sizeof(struct acpi_battery), GFP_KERNEL); - if (!battery) - return_VALUE(-ENOMEM); - memset(battery, 0, sizeof(struct acpi_battery)); - - battery->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_BATTERY_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_BATTERY_CLASS); - acpi_driver_data(device) = battery; - - result = acpi_battery_check(battery); - if (0 != result) - goto end; - - result = acpi_battery_add_fs(device); - if (0 != result) - goto end; - - status = acpi_install_notify_handler(battery->handle, - ACPI_DEVICE_NOTIFY, acpi_battery_notify, battery); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); - result = -ENODEV; - goto end; - } - - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", - ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), - device->status.battery_present?"present":"absent"); - -end: - if (0 != result) { - acpi_battery_remove_fs(device); - kfree(battery); - } - - return_VALUE(result); -} - - -static int -acpi_battery_remove ( - struct acpi_device *device, - int type) -{ - acpi_status status = 0; - struct acpi_battery *battery = NULL; - - ACPI_FUNCTION_TRACE("acpi_battery_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - battery = (struct acpi_battery *) acpi_driver_data(device); - - status = acpi_remove_notify_handler(battery->handle, - ACPI_DEVICE_NOTIFY, acpi_battery_notify); - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - - acpi_battery_remove_fs(device); - - kfree(battery); - - return_VALUE(0); -} - - -static int __init -acpi_battery_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_battery_init"); - - result = acpi_bus_register_driver(&acpi_battery_driver); - if (0 > result) { - remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -static void __exit -acpi_battery_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_battery_exit"); - - result = acpi_bus_unregister_driver(&acpi_battery_driver); - if (0 == result) - remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); - - return_VOID; -} - - -module_init(acpi_battery_init); -module_exit(acpi_battery_exit); diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2197 +0,0 @@ -/* - * acpi_bus.c - ACPI Bus Driver ($Revision: 72 $) - * - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" -#include "include/acinterp.h" /* for acpi_ex_eisa_id_to_string() */ - - -#define _COMPONENT ACPI_BUS_COMPONENT -ACPI_MODULE_NAME ("acpi_bus") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_BUS_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - -FADT_DESCRIPTOR acpi_fadt; -static u8 acpi_disabled; -struct acpi_device *acpi_root; -struct proc_dir_entry *acpi_root_dir; - -#define STRUCT_TO_INT(s) (*((int*)&s)) - -/* - * POLICY: If *anything* doesn't work, put it on the blacklist. - * If they are critical errors, mark it critical, and abort driver load. - */ -static struct acpi_blacklist_item acpi_blacklist[] __initdata = -{ - /* Portege 7020, BIOS 8.10 */ - {"TOSHIB", "7020CT ", 0x19991112, ACPI_TABLE_DSDT, all_versions, "Implicit Return", 0}, - /* Portege 4030 */ - {"TOSHIB", "4030 ", 0x19991112, ACPI_TABLE_DSDT, all_versions, "Implicit Return", 0}, - /* Portege 310/320, BIOS 7.1 */ - {"TOSHIB", "310 ", 0x19990511, ACPI_TABLE_DSDT, all_versions, "Implicit Return", 0}, - /* Seattle 2, old bios rev. */ - {"INTEL ", "440BX ", 0x00001000, ACPI_TABLE_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* ASUS K7M */ - {"ASUS ", "K7M ", 0x00001000, ACPI_TABLE_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* Intel 810 Motherboard? */ - {"MNTRAL", "MO81010A", 0x00000012, ACPI_TABLE_DSDT, less_than_or_equal, "Field beyond end of region", 0}, - /* Compaq Presario 1700 */ - {"PTLTD ", " DSDT ", 0x06040000, ACPI_TABLE_DSDT, less_than_or_equal, "Multiple problems", 1}, - /* Sony FX120, FX140, FX150? */ - {"SONY ", "U0 ", 0x20010313, ACPI_TABLE_DSDT, less_than_or_equal, "ACPI driver problem", 1}, - /* Compaq Presario 800, Insyde BIOS */ - {"INT440", "SYSFexxx", 0x00001001, ACPI_TABLE_DSDT, less_than_or_equal, "Does not use _REG to protect EC OpRegions", 1}, - /* IBM 600E - _ADR should return 7, but it returns 1 */ - {"IBM ", "TP600E ", 0x00000105, ACPI_TABLE_DSDT, less_than_or_equal, "Incorrect _ADR", 1}, - {""} -}; - - -/* -------------------------------------------------------------------------- - Linux Driver Model (LDM) Support - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_LDM - -static int acpi_device_probe(struct device *dev); -static int acpi_device_remove(struct device *dev, u32 flags); -static int acpi_device_suspend(struct device *dev, u32 state, u32 stage); -static int acpi_device_resume(struct device *dev, u32 stage); - -static struct device_driver acpi_bus_driver = { - probe: acpi_device_probe, - remove: acpi_device_remove, - suspend: acpi_device_suspend, - resume: acpi_device_resume, -}; - - -static int -acpi_device_probe ( - struct device *dev) -{ - ACPI_FUNCTION_TRACE("acpi_device_probe"); - - if (!dev) - return_VALUE(-EINVAL); - - /* TBD */ - - return_VALUE(0); -} - - -static int -acpi_device_remove ( - struct device *dev, - u32 flags) -{ - ACPI_FUNCTION_TRACE("acpi_device_remove"); - - if (!dev) - return_VALUE(-EINVAL); - - /* TBD */ - - return_VALUE(0); -} - - -static int -acpi_device_suspend ( - struct device *dev, - u32 state, - u32 stage) -{ - ACPI_FUNCTION_TRACE("acpi_device_suspend"); - - if (!dev) - return_VALUE(-EINVAL); - - /* TBD */ - - return_VALUE(0); -} - - -static int -acpi_device_resume ( - struct device *dev, - u32 stage) -{ - ACPI_FUNCTION_TRACE("acpi_device_resume"); - - if (!dev) - return_VALUE(-EINVAL); - - /* TBD */ - - return_VALUE(0); -} - -#if 0 /* not used ATM */ -static int -acpi_platform_add ( - struct device *dev) -{ - ACPI_FUNCTION_TRACE("acpi_platform_add"); - - if (!dev) - return -EINVAL; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s (%s) added\n", - dev->name, dev->bus_id)); - - /* TBD */ - - return_VALUE(0); -} - - -static int -acpi_platform_remove ( - struct device *dev) -{ - ACPI_FUNCTION_TRACE("acpi_platform_add"); - - if (!dev) - return -EINVAL; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s (%s) removed\n", - dev->name, dev->bus_id)); - - /* TBD */ - - return_VALUE(0); -} -#endif /* unused */ - - -#endif /*CONFIG_LDM*/ - - -static int -acpi_device_register ( - struct acpi_device *device, - struct acpi_device *parent) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_device_register"); - - if (!device) - return_VALUE(-EINVAL); - -#ifdef CONFIG_LDM - sprintf(device->dev.name, "ACPI device %s:%s", - device->pnp.hardware_id, device->pnp.unique_id); - strncpy(device->dev.bus_id, device->pnp.bus_id, sizeof(acpi_bus_id)); - if (parent) - device->dev.parent = &parent->dev; - device->dev.driver = &acpi_bus_driver; - - result = device_register(&device->dev); -#endif /*CONFIG_LDM*/ - - return_VALUE(result); -} - - -static int -acpi_device_unregister ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_device_unregister"); - - if (!device) - return_VALUE(-EINVAL); - -#ifdef CONFIG_LDM - put_device(&device->dev); -#endif /*CONFIG_LDM*/ - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Device Management - -------------------------------------------------------------------------- */ - -static void -acpi_bus_data_handler ( - acpi_handle handle, - u32 function, - void *context) -{ - ACPI_FUNCTION_TRACE("acpi_bus_data_handler"); - - /* TBD */ - - return_VOID; -} - - -int -acpi_bus_get_device ( - acpi_handle handle, - struct acpi_device **device) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_bus_get_device"); - - if (!device) - return_VALUE(-EINVAL); - - /* TBD: Support fixed-feature devices */ - - status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device); - if (ACPI_FAILURE(status) || !*device) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context for object [%p]\n", - handle)); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - -int -acpi_bus_get_status ( - struct acpi_device *device) -{ - acpi_status status = AE_OK; - unsigned long sta = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_get_status"); - - if (!device) - return_VALUE(-EINVAL); - - /* - * Evaluate _STA if present. - */ - if (device->flags.dynamic_status) { - status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - STRUCT_TO_INT(device->status) = (int) sta; - } - - /* - * Otherwise we assume the status of our parent (unless we don't - * have one, in which case status is implied). - */ - else if (device->parent) - device->status = device->parent->status; - else - STRUCT_TO_INT(device->status) = 0x0F; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", - device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status))); - - return_VALUE(0); -} - - -/* -static int -acpi_bus_create_device_fs (struct device *device) -{ - ACPI_FUNCTION_TRACE("acpi_bus_create_device_fs"); - - if (!device) - return_VALUE(-EINVAL); - - if (device->dir.entry) - return_VALUE(-EEXIST); - - if (!device->parent) - device->dir.entry = proc_mkdir(device->pnp.bus_id, NULL); - else - device->dir.entry = proc_mkdir(device->pnp.bus_id, - device->parent->fs.entry); - - if (!device->dir.entry) { - printk(KERN_ERR PREFIX "Unable to create fs entry '%s'\n", - device->pnp.bus_id); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -static int -acpi_bus_remove_device_fs (struct device *device) -{ - ACPI_FUNCTION_TRACE("acpi_bus_create_device_fs"); - - if (!device) - return_VALUE(-EINVAL); - - if (!device->dir.entry) - return_VALUE(-ENODEV); - - if (!device->parent) - remove_proc_entry(device->pnp_bus_id, NULL); - else - remove_proc_entry(device->pnp.bus_id, device->parent->fs.entry); - - device->dir.entry = NULL; - - return_VALUE(0); -} -*/ - - -/* -------------------------------------------------------------------------- - Power Management - -------------------------------------------------------------------------- */ - -int -acpi_bus_get_power ( - acpi_handle handle, - int *state) -{ - int result = 0; - acpi_status status = 0; - struct acpi_device *device = NULL; - unsigned long psc = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_get_power"); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) - return_VALUE(result); - - *state = ACPI_STATE_UNKNOWN; - - if (!device->flags.power_manageable) { - /* TBD: Non-recursive algorithm for walking up hierarchy */ - if (device->parent) - *state = device->parent->power.state; - else - *state = ACPI_STATE_D0; - } - else { - /* - * Get the device's power state either directly (via _PSC) or - * indirectly (via power resources). - */ - if (device->power.flags.explicit_get) { - status = acpi_evaluate_integer(device->handle, "_PSC", - NULL, &psc); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - device->power.state = (int) psc; - } - else if (device->power.flags.power_resources) { - result = acpi_power_get_inferred_state(device); - if (0 != result) - return_VALUE(result); - } - - *state = device->power.state; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", - device->pnp.bus_id, device->power.state)); - - return_VALUE(0); -} - - -int -acpi_bus_set_power ( - acpi_handle handle, - int state) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_device *device = NULL; - char object_name[5] = {'_','P','S','0'+state,'\0'}; - - ACPI_FUNCTION_TRACE("acpi_bus_set_power"); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) - return_VALUE(result); - - if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) - return_VALUE(-EINVAL); - - /* Make sure this is a valid target state */ - - if (!device->flags.power_manageable) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n")); - return_VALUE(-ENODEV); - } - if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state)); - return_VALUE(0); - } - if (!device->power.states[state].flags.valid) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state)); - return_VALUE(-ENODEV); - } - if (device->parent && (state < device->parent->power.state)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n")); - return_VALUE(-ENODEV); - } - - /* - * Transition Power - * ---------------- - * On transitions to a high-powered state we first apply power (via - * power resources) then evalute _PSx. Conversly for transitions to - * a lower-powered state. - */ - if (state < device->power.state) { - if (device->power.flags.power_resources) { - result = acpi_power_transition(device, state); - if (0 != result) - goto end; - } - if (device->power.states[state].flags.explicit_set) { - status = acpi_evaluate_object(device->handle, - object_name, NULL, NULL); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } - } - } - else { - if (device->power.states[state].flags.explicit_set) { - status = acpi_evaluate_object(device->handle, - object_name, NULL, NULL); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } - } - if (device->power.flags.power_resources) { - result = acpi_power_transition(device, state); - if (0 != result) - goto end; - } - } - -end: - if (0 != result) - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n", - device->pnp.bus_id, state)); - else - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n", - device->pnp.bus_id, state)); - - return_VALUE(result); -} - - -static int -acpi_bus_get_power_flags ( - struct acpi_device *device) -{ - acpi_status status = 0; - acpi_handle handle = 0; - u32 i = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_get_power_flags"); - - if (!device) - return -ENODEV; - - /* - * Power Management Flags - */ - status = acpi_get_handle(device->handle, "_PSC", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.explicit_get = 1; - status = acpi_get_handle(device->handle, "_IRC", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.inrush_current = 1; - status = acpi_get_handle(device->handle, "_PRW", &handle); - if (ACPI_SUCCESS(status)) - device->power.flags.wake_capable = 1; - - /* - * Enumerate supported power management states - */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { - struct acpi_device_power_state *ps = &device->power.states[i]; - char object_name[5] = {'_','P','R','0'+i,'\0'}; - - /* Evaluate "_PRx" to se if power resources are referenced */ - acpi_evaluate_reference(device->handle, object_name, NULL, - &ps->resources); - if (ps->resources.count) { - device->power.flags.power_resources = 1; - ps->flags.valid = 1; - } - - /* Evaluate "_PSx" to see if we can do explicit sets */ - object_name[2] = 'S'; - status = acpi_get_handle(device->handle, object_name, &handle); - if (ACPI_SUCCESS(status)) { - ps->flags.explicit_set = 1; - ps->flags.valid = 1; - } - - /* State is valid if we have some power control */ - if (ps->resources.count || ps->flags.explicit_set) - ps->flags.valid = 1; - - ps->power = -1; /* Unknown - driver assigned */ - ps->latency = -1; /* Unknown - driver assigned */ - } - - /* Set defaults for D0 and D3 states (always valid) */ - device->power.states[ACPI_STATE_D0].flags.valid = 1; - device->power.states[ACPI_STATE_D0].power = 100; - device->power.states[ACPI_STATE_D3].flags.valid = 1; - device->power.states[ACPI_STATE_D3].power = 0; - - /* - * System Power States - * ------------------- - */ - /* TBD: S1-S4 power state support and resource requirements. */ - /* - for (i=ACPI_STATE_S1; ihandle, name, NULL, - &state); - if (ACPI_FAILURE(status)) - continue; - } - */ - - /* TBD: System wake support and resource requirements. */ - - device->power.state = ACPI_STATE_UNKNOWN; - - return 0; -} - - -/* -------------------------------------------------------------------------- - Performance Management - -------------------------------------------------------------------------- */ - -static int -acpi_bus_get_perf_flags ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_bus_get_perf_flags"); - - if (!device) - return -ENODEV; - - device->performance.state = ACPI_STATE_UNKNOWN; - - return 0; -} - - -/* -------------------------------------------------------------------------- - Event Management - -------------------------------------------------------------------------- */ - -static spinlock_t acpi_bus_event_lock = SPIN_LOCK_UNLOCKED; - -LIST_HEAD(acpi_bus_event_list); -DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); - -extern int event_is_open; - -int -acpi_bus_generate_event ( - struct acpi_device *device, - u8 type, - int data) -{ - struct acpi_bus_event *event = NULL; - u32 flags = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_generate_event"); - - if (!device) - return_VALUE(-EINVAL); - - /* drop event on the floor if no one's listening */ - if (!event_is_open) - return_VALUE(0); - - event = kmalloc(sizeof(struct acpi_bus_event), GFP_KERNEL); - if (!event) - return_VALUE(-ENOMEM); - - sprintf(event->device_class, "%s", device->pnp.device_class); - sprintf(event->bus_id, "%s", device->pnp.bus_id); - event->type = type; - event->data = data; - - spin_lock_irqsave(&acpi_bus_event_lock, flags); - list_add_tail(&event->node, &acpi_bus_event_list); - spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - wake_up_interruptible(&acpi_bus_event_queue); - - return_VALUE(0); -} - -int -acpi_bus_receive_event ( - struct acpi_bus_event *event) -{ - u32 flags = 0; - struct acpi_bus_event *entry = NULL; - - DECLARE_WAITQUEUE(wait, current); - - ACPI_FUNCTION_TRACE("acpi_bus_receive_event"); - - if (!event) - return -EINVAL; - - if (list_empty(&acpi_bus_event_list)) { - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&acpi_bus_event_queue, &wait); - - if (list_empty(&acpi_bus_event_list)) - schedule(); - - remove_wait_queue(&acpi_bus_event_queue, &wait); - set_current_state(TASK_RUNNING); - - if (signal_pending(current)) - return_VALUE(-ERESTARTSYS); - } - - spin_lock_irqsave(&acpi_bus_event_lock, flags); - entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); - if (entry) - list_del(&entry->node); - spin_unlock_irqrestore(&acpi_bus_event_lock, flags); - - if (!entry) - return_VALUE(-ENODEV); - - memcpy(event, entry, sizeof(struct acpi_bus_event)); - - kfree(entry); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Namespace Management - -------------------------------------------------------------------------- */ - -#define WALK_UP 0 -#define WALK_DOWN 1 - -typedef int (*acpi_bus_walk_callback)(struct acpi_device*, int, void*); - -#define HAS_CHILDREN(d) ((d)->children.next != &((d)->children)) -#define HAS_SIBLINGS(d) (((d)->parent) && ((d)->node.next != &(d)->parent->children)) -#define NODE_TO_DEVICE(n) (list_entry(n, struct acpi_device, node)) - - -/** - * acpi_bus_walk - * ------------- - * Used to walk the ACPI Bus's device namespace. Can walk down (depth-first) - * or up. Able to parse starting at any node in the namespace. Note that a - * callback return value of -ELOOP will terminate the walk. - * - * @start: starting point - * callback: function to call for every device encountered while parsing - * direction: direction to parse (up or down) - * @data: context for this search operation - */ -static int -acpi_bus_walk ( - struct acpi_device *start, - acpi_bus_walk_callback callback, - int direction, - void *data) -{ - int result = 0; - int level = 0; - struct acpi_device *device = NULL; - - if (!start || !callback) - return -EINVAL; - - device = start; - - /* - * Parse Namespace - * --------------- - * Parse a given subtree (specified by start) in the given direction. - * Walking 'up' simply means that we execute the callback on leaf - * devices prior to their parents (useful for things like removing - * or powering down a subtree). - */ - - while (device) { - - if (direction == WALK_DOWN) - if (-ELOOP == callback(device, level, data)) - break; - - /* Depth First */ - - if (HAS_CHILDREN(device)) { - device = NODE_TO_DEVICE(device->children.next); - ++level; - continue; - } - - if (direction == WALK_UP) - if (-ELOOP == callback(device, level, data)) - break; - - /* Now Breadth */ - - if (HAS_SIBLINGS(device)) { - device = NODE_TO_DEVICE(device->node.next); - continue; - } - - /* Scope Exhausted - Find Next */ - - while ((device = device->parent)) { - --level; - if (HAS_SIBLINGS(device)) { - device = NODE_TO_DEVICE(device->node.next); - break; - } - } - } - - if ((direction == WALK_UP) && (result == 0)) - callback(start, level, data); - - return result; -} - - -/* -------------------------------------------------------------------------- - Notification Handling - -------------------------------------------------------------------------- */ - -static int -acpi_bus_check_device ( - struct acpi_device *device, - int *status_changed) -{ - acpi_status status = 0; - struct acpi_device_status old_status; - - ACPI_FUNCTION_TRACE("acpi_bus_check_device"); - - if (!device) - return_VALUE(-EINVAL); - - if (status_changed) - *status_changed = 0; - - old_status = device->status; - - /* - * Make sure this device's parent is present before we go about - * messing with the device. - */ - if (device->parent && !device->parent->status.present) { - device->status = device->parent->status; - if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { - if (status_changed) - *status_changed = 1; - } - return_VALUE(0); - } - - status = acpi_bus_get_status(device); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) - return_VALUE(0); - - if (status_changed) - *status_changed = 1; - - /* - * Device Insertion/Removal - */ - if ((device->status.present) && !(old_status.present)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); - /* TBD: Handle device insertion */ - } - else if (!(device->status.present) && (old_status.present)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); - /* TBD: Handle device removal */ - } - - return_VALUE(0); -} - - -static int -acpi_bus_check_scope ( - struct acpi_device *device) -{ - int result = 0; - int status_changed = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_check_scope"); - - if (!device) - return_VALUE(-EINVAL); - - /* Status Change? */ - result = acpi_bus_check_device(device, &status_changed); - if (0 != result) - return_VALUE(result); - - if (!status_changed) - return_VALUE(0); - - /* - * TBD: Enumerate child devices within this device's scope and - * run acpi_bus_check_device()'s on them. - */ - - return_VALUE(0); -} - - -/** - * acpi_bus_notify - * --------------- - * Callback for all 'system-level' device notifications (values 0x00-0x7F). - */ -static void -acpi_bus_notify ( - acpi_handle handle, - u32 type, - void *data) -{ - int result = 0; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_notify"); - - if (0 != acpi_bus_get_device(handle, &device)) - return_VOID; - - switch (type) { - - case ACPI_NOTIFY_BUS_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS CHECK notification for device [%s]\n", - device->pnp.bus_id)); - result = acpi_bus_check_scope(device); - /* - * TBD: We'll need to outsource certain events to non-ACPI - * drivers via the device manager (device.c). - */ - break; - - case ACPI_NOTIFY_DEVICE_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%s]\n", - device->pnp.bus_id)); - result = acpi_bus_check_device(device, NULL); - /* - * TBD: We'll need to outsource certain events to non-ACPI - * drivers via the device manager (device.c). - */ - break; - - case ACPI_NOTIFY_DEVICE_WAKE: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD */ - break; - - case ACPI_NOTIFY_EJECT_REQUEST: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD */ - break; - - case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD: Exactly what does 'light' mean? */ - break; - - case ACPI_NOTIFY_FREQUENCY_MISMATCH: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD */ - break; - - case ACPI_NOTIFY_BUS_MODE_MISMATCH: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD */ - break; - - case ACPI_NOTIFY_POWER_FAULT: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received POWER FAULT notification for device [%s]\n", - device->pnp.bus_id)); - /* TBD */ - break; - - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n", - type)); - break; - } - - return_VOID; -} - - -/* -------------------------------------------------------------------------- - Driver Management - -------------------------------------------------------------------------- */ - -static LIST_HEAD(acpi_bus_drivers); -static DECLARE_MUTEX(acpi_bus_drivers_lock); - - -/** - * acpi_bus_match - * -------------- - * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it - * matches the specified driver's criteria. - */ -static int -acpi_bus_match ( - struct acpi_device *device, - struct acpi_driver *driver) -{ - - if (!device || !driver) - return -EINVAL; - - if (device->flags.hardware_id) { - if (0 != strstr(driver->ids, device->pnp.hardware_id)) - return 0; - } - - if (device->flags.compatible_ids) { - acpi_status status = AE_OK; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_object *object = NULL; - char cid[256]; - - memset(cid, 0, sizeof(cid)); - - status = acpi_evaluate_object(device->handle, "_CID", NULL, - &buffer); - if (ACPI_FAILURE(status) || !buffer.pointer) - return -ENOENT; - - object = (acpi_object *) buffer.pointer; - - switch (object->type) { - case ACPI_TYPE_INTEGER: - acpi_ex_eisa_id_to_string((u32) object->integer.value, - cid); - break; - case ACPI_TYPE_STRING: - strncpy(cid, object->string.pointer, sizeof(cid) - 1); - break; - case ACPI_TYPE_PACKAGE: - /* TBD: Support CID packages */ - break; - } - - if (!cid[0]) - return -ENOENT; - - if (0 != strstr(driver->ids, cid)) - return 0; - } - - return -ENOENT; -} - - -/** - * acpi_bus_driver_init - * -------------------- - * Used to initialize a device via its device driver. Called whenever a - * driver is bound to a device. Invokes the driver's add() and start() ops. - */ -static int -acpi_bus_driver_init ( - struct acpi_device *device, - struct acpi_driver *driver) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_driver_init"); - - if (!device || !driver) - return_VALUE(-EINVAL); - - if (!driver->ops.add) - return_VALUE(-ENOSYS); - - result = driver->ops.add(device); - if (0 != result) { - device->driver = NULL; - acpi_driver_data(device) = NULL; - return_VALUE(result); - } - - /* - * TBD - Configuration Management: Assign resources to device based - * upon possible configuration and currently allocated resources. - */ - - if (driver->ops.start) { - result = driver->ops.start(device); - if ((0 != result) && (driver->ops.remove)) - driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); - return_VALUE(result); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); - -#ifdef CONFIG_LDM - /* - * Update the device information (in the global device hierarchy) now - * that there's a driver bound to it. - */ - strncpy(device->dev.name, device->pnp.device_name, - sizeof(device->dev.name)); -#endif - - if (driver->ops.scan) { - driver->ops.scan(device); - } - - return_VALUE(0); -} - - -/** - * acpi_bus_attach - * ------------- - * Callback for acpi_bus_walk() used to find devices that match a specific - * driver's criteria and then attach the driver. - */ -static int -acpi_bus_attach ( - struct acpi_device *device, - int level, - void *data) -{ - int result = 0; - struct acpi_driver *driver = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_attach"); - - if (!device || !data) - return_VALUE(-EINVAL); - - driver = (struct acpi_driver *) data; - - if (device->driver) - return_VALUE(-EEXIST); - - if (!device->status.present) - return_VALUE(-ENODEV); - - result = acpi_bus_match(device, driver); - if (0 != result) - return_VALUE(result); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", - driver->name, device->pnp.bus_id)); - - result = acpi_bus_driver_init(device, driver); - if (0 != result) - return_VALUE(result); - - down(&acpi_bus_drivers_lock); - ++driver->references; - up(&acpi_bus_drivers_lock); - - return_VALUE(0); -} - - -/** - * acpi_bus_unattach - * ----------------- - * Callback for acpi_bus_walk() used to find devices that match a specific - * driver's criteria and unattach the driver. - */ -static int -acpi_bus_unattach ( - struct acpi_device *device, - int level, - void *data) -{ - int result = 0; - struct acpi_driver *driver = (struct acpi_driver *) data; - - ACPI_FUNCTION_TRACE("acpi_bus_unattach"); - - if (!device || !driver) - return_VALUE(-EINVAL); - - if (device->driver != driver) - return_VALUE(-ENOENT); - - if (!driver->ops.remove) - return_VALUE(-ENOSYS); - - result = driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); - if (0 != result) - return_VALUE(result); - - device->driver = NULL; - acpi_driver_data(device) = NULL; - - down(&acpi_bus_drivers_lock); - driver->references--; - up(&acpi_bus_drivers_lock); - - return_VALUE(0); -} - - -/** - * acpi_bus_find_driver - * -------------------- - * Parses the list of registered drivers looking for a driver applicable for - * the specified device. - */ -static int -acpi_bus_find_driver ( - struct acpi_device *device) -{ - int result = -ENODEV; - struct list_head *entry = NULL; - struct acpi_driver *driver = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_find_driver"); - - if (!device || device->driver) - return_VALUE(-EINVAL); - - down(&acpi_bus_drivers_lock); - - list_for_each(entry, &acpi_bus_drivers) { - - driver = list_entry(entry, struct acpi_driver, node); - - if (0 != acpi_bus_match(device, driver)) - continue; - - result = acpi_bus_driver_init(device, driver); - if (0 == result) - ++driver->references; - - break; - } - - up(&acpi_bus_drivers_lock); - - return_VALUE(result); -} - - -/** - * acpi_bus_register_driver - * ------------------------ - * Registers a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and binds. - */ -int -acpi_bus_register_driver ( - struct acpi_driver *driver) -{ - ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); - - if (!driver) - return_VALUE(-EINVAL); - - down(&acpi_bus_drivers_lock); - list_add_tail(&driver->node, &acpi_bus_drivers); - up(&acpi_bus_drivers_lock); - - acpi_bus_walk(acpi_root, acpi_bus_attach, - WALK_DOWN, driver); - - return_VALUE(driver->references); -} - - -/** - * acpi_bus_unregister_driver - * -------------------------- - * Unregisters a driver with the ACPI bus. Searches the namespace for all - * devices that match the driver's criteria and unbinds. - */ -int -acpi_bus_unregister_driver ( - struct acpi_driver *driver) -{ - ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver"); - - if (!driver) - return_VALUE(-EINVAL); - - acpi_bus_walk(acpi_root, acpi_bus_unattach, WALK_UP, driver); - - if (driver->references) - return_VALUE(driver->references); - - down(&acpi_bus_drivers_lock); - list_del(&driver->node); - up(&acpi_bus_drivers_lock); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Device Enumeration - -------------------------------------------------------------------------- */ - -static int -acpi_bus_get_flags ( - struct acpi_device *device) -{ - acpi_status status = AE_OK; - acpi_handle temp = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_get_flags"); - - /* Presence of _STA indicates 'dynamic_status' */ - status = acpi_get_handle(device->handle, "_STA", &temp); - if (ACPI_SUCCESS(status)) - device->flags.dynamic_status = 1; - - /* Presence of _CID indicates 'compatible_ids' */ - status = acpi_get_handle(device->handle, "_CID", &temp); - if (ACPI_SUCCESS(status)) - device->flags.compatible_ids = 1; - - /* Presence of _RMV indicates 'removable' */ - status = acpi_get_handle(device->handle, "_RMV", &temp); - if (ACPI_SUCCESS(status)) - device->flags.removable = 1; - - /* Presence of _EJD|_EJ0 indicates 'ejectable' */ - status = acpi_get_handle(device->handle, "_EJD", &temp); - if (ACPI_SUCCESS(status)) - device->flags.ejectable = 1; - else { - status = acpi_get_handle(device->handle, "_EJ0", &temp); - if (ACPI_SUCCESS(status)) - device->flags.ejectable = 1; - } - - /* Presence of _LCK indicates 'lockable' */ - status = acpi_get_handle(device->handle, "_LCK", &temp); - if (ACPI_SUCCESS(status)) - device->flags.lockable = 1; - - /* Presence of _PS0|_PR0 indicates 'power manageable' */ - status = acpi_get_handle(device->handle, "_PS0", &temp); - if (ACPI_FAILURE(status)) - status = acpi_get_handle(device->handle, "_PR0", &temp); - if (ACPI_SUCCESS(status)) - device->flags.power_manageable = 1; - - /* TBD: Peformance management */ - - return_VALUE(0); -} - - -static int -acpi_bus_add ( - struct acpi_device **child, - struct acpi_device *parent, - acpi_handle handle, - int type) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_device *device = NULL; - char bus_id[5] = {'?',0}; - acpi_buffer buffer = {sizeof(bus_id), bus_id}; - acpi_device_info info; - char *hid = NULL; - char *uid = NULL; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_add"); - - if (!child) - return_VALUE(-EINVAL); - - device = kmalloc(sizeof(struct acpi_device), GFP_KERNEL); - if (!device) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); - return_VALUE(-ENOMEM); - } - memset(device, 0, sizeof(struct acpi_device)); - - device->handle = handle; - device->parent = parent; - - memset(&info, 0, sizeof(acpi_device_info)); - - /* - * Bus ID - * ------ - * The device's Bus ID is simply the object name. - * TBD: Shouldn't this value be unique (within the ACPI namespace)? - */ - switch (type) { - case ACPI_BUS_TYPE_SYSTEM: - sprintf(device->pnp.bus_id, "%s", "ACPI"); - break; - case ACPI_BUS_TYPE_POWER_BUTTON: - sprintf(device->pnp.bus_id, "%s", "PWRF"); - break; - case ACPI_BUS_TYPE_SLEEP_BUTTON: - sprintf(device->pnp.bus_id, "%s", "SLPF"); - break; - default: - acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); - /* Clean up trailing underscores (if any) */ - for (i = 3; i > 1; i--) { - if (bus_id[i] == '_') - bus_id[i] = '\0'; - else - break; - } - sprintf(device->pnp.bus_id, "%s", bus_id); - break; - } - - /* - * Flags - * ----- - * Get prior to calling acpi_bus_get_status() so we know whether - * or not _STA is present. Note that we only look for object - * handles -- cannot evaluate objects until we know the device is - * present and properly initialized. - */ - result = acpi_bus_get_flags(device); - if (0 != result) - goto end; - - /* - * Status - * ------ - * See if the device is present. We always assume that non-Device() - * objects (e.g. thermal zones, power resources, processors, etc.) are - * present, functioning, etc. (at least when parent object is present). - * Note that _STA has a different meaning for some objects (e.g. - * power resources) so we need to be careful how we use it. - */ - switch (type) { - case ACPI_BUS_TYPE_DEVICE: - result = acpi_bus_get_status(device); - if (!result) - break; - if (!device->status.present) - result = -ENOENT; - goto end; - default: - STRUCT_TO_INT(device->status) = 0x0F; - break; - } - - /* - * Initialize Device - * ----------------- - * TBD: Synch with Core's enumeration/initialization process. - */ - - /* - * Hardware ID, Unique ID, & Bus Address - * ------------------------------------- - */ - switch (type) { - case ACPI_BUS_TYPE_DEVICE: - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading device info\n")); - result = -ENODEV; - goto end; - } - /* Clean up info strings (not NULL terminated) */ - info.hardware_id[sizeof(info.hardware_id)-1] = '\0'; - info.unique_id[sizeof(info.unique_id)-1] = '\0'; - if (info.valid & ACPI_VALID_HID) - hid = info.hardware_id; - if (info.valid & ACPI_VALID_UID) - uid = info.unique_id; - if (info.valid & ACPI_VALID_ADR) { - device->pnp.bus_address = info.address; - device->flags.bus_address = 1; - } - break; - case ACPI_BUS_TYPE_POWER: - hid = ACPI_POWER_HID; - break; - case ACPI_BUS_TYPE_PROCESSOR: - hid = ACPI_PROCESSOR_HID; - break; - case ACPI_BUS_TYPE_SYSTEM: - hid = ACPI_SYSTEM_HID; - break; - case ACPI_BUS_TYPE_THERMAL: - hid = ACPI_THERMAL_HID; - break; - case ACPI_BUS_TYPE_POWER_BUTTON: - hid = ACPI_BUTTON_HID_POWERF; - break; - case ACPI_BUS_TYPE_SLEEP_BUTTON: - hid = ACPI_BUTTON_HID_SLEEPF; - break; - } - - /* - * \_SB - * ---- - * Fix for the system root bus device -- the only root-level device. - */ - if ((parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { - hid = ACPI_BUS_HID; - sprintf(device->pnp.device_name, "%s", ACPI_BUS_DEVICE_NAME); - sprintf(device->pnp.device_class, "%s", ACPI_BUS_CLASS); - } - - if (hid) { - sprintf(device->pnp.hardware_id, "%s", hid); - device->flags.hardware_id = 1; - } - if (uid) { - sprintf(device->pnp.unique_id, "%s", uid); - device->flags.unique_id = 1; - } - - /* - * Power Management - * ---------------- - */ - if (device->flags.power_manageable) { - result = acpi_bus_get_power_flags(device); - if (0 != result) - goto end; - } - - /* - * Performance Management - * ---------------------- - */ - if (device->flags.performance_manageable) { - result = acpi_bus_get_perf_flags(device); - if (0 != result) - goto end; - } - - /* - * Context - * ------- - * Attach this 'struct acpi_device' to the ACPI object. This makes - * resolutions from handle->device very efficient. Note that we need - * to be careful with fixed-feature devices as they all attach to the - * root object. - */ - switch (type) { - case ACPI_BUS_TYPE_POWER_BUTTON: - case ACPI_BUS_TYPE_SLEEP_BUTTON: - break; - default: - status = acpi_attach_data(device->handle, - acpi_bus_data_handler, device); - break; - } - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error attaching device data\n")); - result = -ENODEV; - goto end; - } - - /* - * Linkage - * ------- - * Link this device to its parent and siblings. - */ - INIT_LIST_HEAD(&device->children); - if (!device->parent) - INIT_LIST_HEAD(&device->node); - else - list_add_tail(&device->node, &device->parent->children); - -#ifdef CONFIG_ACPI_DEBUG - { - char *type_string = NULL; - char name[80] = {'?','\0'}; - acpi_buffer buffer = {sizeof(name), name}; - - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - - switch (type) { - case ACPI_BUS_TYPE_DEVICE: - type_string = "Device"; - break; - case ACPI_BUS_TYPE_POWER: - type_string = "Power Resource"; - break; - case ACPI_BUS_TYPE_PROCESSOR: - type_string = "Processor"; - break; - case ACPI_BUS_TYPE_SYSTEM: - type_string = "System"; - break; - case ACPI_BUS_TYPE_THERMAL: - type_string = "Thermal Zone"; - break; - case ACPI_BUS_TYPE_POWER_BUTTON: - type_string = "Power Button"; - sprintf(name, "PWRB"); - break; - case ACPI_BUS_TYPE_SLEEP_BUTTON: - type_string = "Sleep Button"; - sprintf(name, "SLPB"); - break; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s %s [%p]\n", - type_string, name, handle)); - } -#endif /*CONFIG_ACPI_DEBUG*/ - - /* - * Global Device Hierarchy: - * ------------------------ - * Register this device with the global device hierarchy. - */ - acpi_device_register(device, parent); - - /* - * Bind _ADR-Based Devices - * ----------------------- - * If there's a a bus address (_ADR) then we utilize the parent's - * 'bind' function (if exists) to bind the ACPI- and natively- - * enumerated device representations. - */ - if (device->flags.bus_address) { - if (device->parent && device->parent->ops.bind) - device->parent->ops.bind(device); - } - - /* - * Locate & Attach Driver - * ---------------------- - * If there's a hardware id (_HID) or compatible ids (_CID) we check - * to see if there's a driver installed for this kind of device. Note - * that drivers can install before or after a device in enumerated. - * - * TBD: Assumes LDM provides driver hot-plug capability. - */ - if (device->flags.hardware_id || device->flags.compatible_ids) - acpi_bus_find_driver(device); - -end: - if (0 != result) { - kfree(device); - return_VALUE(result); - } - - *child = device; - - return_VALUE(0); -} - - -static int -acpi_bus_remove ( - struct acpi_device *device, - int type) -{ - ACPI_FUNCTION_TRACE("acpi_bus_remove"); - - if (!device) - return_VALUE(-ENODEV); - - acpi_device_unregister(device); - - kfree(device); - - return_VALUE(0); -} - - -int -acpi_bus_scan ( - struct acpi_device *start) -{ - acpi_status status = AE_OK; - struct acpi_device *parent = NULL; - struct acpi_device *child = NULL; - acpi_handle phandle = 0; - acpi_handle chandle = 0; - acpi_object_type type = 0; - u32 level = 1; - - ACPI_FUNCTION_TRACE("acpi_bus_scan"); - - if (!start) - return_VALUE(-EINVAL); - - parent = start; - phandle = start->handle; - - /* - * Parse through the ACPI namespace, identify all 'devices', and - * create a new 'struct acpi_device' for each. - */ - while ((level > 0) && parent) { - - status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, - chandle, &chandle); - - /* - * If this scope is exhausted then move our way back up. - */ - if (ACPI_FAILURE(status)) { - level--; - chandle = phandle; - acpi_get_parent(phandle, &phandle); - if (parent->parent) - parent = parent->parent; - continue; - } - - status = acpi_get_type(chandle, &type); - if (ACPI_FAILURE(status)) - continue; - - /* - * If this is a scope object then parse it (depth-first). - */ - if (type == ACPI_TYPE_ANY) { - /* Hack to get around scope identity problem */ - status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, 0, NULL); - if (ACPI_SUCCESS(status)) { - level++; - phandle = chandle; - chandle = 0; - } - continue; - } - - /* - * We're only interested in objects that we consider 'devices'. - */ - switch (type) { - case ACPI_TYPE_DEVICE: - type = ACPI_BUS_TYPE_DEVICE; - break; - case ACPI_TYPE_PROCESSOR: - type = ACPI_BUS_TYPE_PROCESSOR; - break; - case ACPI_TYPE_THERMAL: - type = ACPI_BUS_TYPE_THERMAL; - break; - case ACPI_TYPE_POWER: - type = ACPI_BUS_TYPE_POWER; - break; - default: - continue; - } - - status = acpi_bus_add(&child, parent, chandle, type); - if (ACPI_FAILURE(status)) - continue; - - /* - * If the device is present, enabled, and functioning then - * parse its scope (depth-first). Note that we need to - * represent absent devices to facilitate PnP notifications - * -- but only the subtree head (not all of its children, - * which will be enumerated when the parent is inserted). - * - * TBD: Need notifications and other detection mechanisms - * in place before we can fully implement this. - */ - if (child->status.present) { - status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, - 0, NULL); - if (ACPI_SUCCESS(status)) { - level++; - phandle = chandle; - chandle = 0; - parent = child; - } - } - } - - return_VALUE(0); -} - - -static int -acpi_bus_scan_fixed ( - struct acpi_device *root) -{ - int result = 0; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_scan"); - - if (!root) - return_VALUE(-ENODEV); - - /* - * Enumerate all fixed-feature devices. - */ - if (acpi_fadt.pwr_button == 0) - result = acpi_bus_add(&device, acpi_root, - ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_POWER_BUTTON); - - if (acpi_fadt.sleep_button == 0) - result = acpi_bus_add(&device, acpi_root, - ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_SLEEP_BUTTON); - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - Initialization/Cleanup - -------------------------------------------------------------------------- */ - -int __init -acpi_blacklisted(void) -{ - int i = 0; - int blacklisted = 0; - acpi_table_header table_header; - - while (acpi_blacklist[i].oem_id[0] != '\0') - { - if (!ACPI_SUCCESS(acpi_get_table_header(acpi_blacklist[i].table, 1, &table_header))) { - i++; - continue; - } - - if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { - i++; - continue; - } - - if (strncmp(acpi_blacklist[i].oem_table_id, table_header.oem_table_id, 8)) { - i++; - continue; - } - - if ((acpi_blacklist[i].oem_revision_predicate == all_versions) - || (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal - && table_header.oem_revision <= acpi_blacklist[i].oem_revision) - || (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal - && table_header.oem_revision >= acpi_blacklist[i].oem_revision) - || (acpi_blacklist[i].oem_revision_predicate == equal - && table_header.oem_revision == acpi_blacklist[i].oem_revision)) { - - printk(KERN_ERR PREFIX "Vendor \"%6.6s\" System \"%8.8s\" " - "Revision 0x%x has a known ACPI BIOS problem.\n", - acpi_blacklist[i].oem_id, - acpi_blacklist[i].oem_table_id, - acpi_blacklist[i].oem_revision); - - printk(KERN_ERR PREFIX "Reason: %s. This is a %s error\n", - acpi_blacklist[i].reason, - (acpi_blacklist[i].is_critical_error ? "non-recoverable" : "recoverable")); - - blacklisted = acpi_blacklist[i].is_critical_error; - break; - } - else { - i++; - } - } - - return blacklisted; -} - -static int __init -acpi_bus_init_irq (void) -{ - acpi_status status = AE_OK; - acpi_object arg = {ACPI_TYPE_INTEGER}; - acpi_object_list arg_list = {1, &arg}; - char *message = NULL; - - ACPI_FUNCTION_TRACE("acpi_bus_init_irq"); - - /* - * Let the system know what interrupt model we are using by - * evaluating the \_PIC object, if exists. - */ - - switch (acpi_irq_model) { - case ACPI_IRQ_MODEL_PIC: - message = "PIC"; - break; - case ACPI_IRQ_MODEL_IOAPIC: - message = "IOAPIC"; - break; - case ACPI_IRQ_MODEL_IOSAPIC: - message = "IOSAPIC"; - break; - default: - printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); - return_VALUE(-ENODEV); - } - - printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); - - arg.integer.value = acpi_irq_model; - - status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL); - if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n")); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -static int __init -acpi_bus_init (void) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt}; - int progress = 0; - - ACPI_FUNCTION_TRACE("acpi_bus_init"); - - /* - * [0] Initailize the ACPI Core Subsystem. - */ - status = acpi_initialize_subsystem(); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n"); - result = -ENODEV; - goto end; - } - - progress++; - - /* - * [1] Load the ACPI tables. - */ - status = acpi_load_tables(); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n"); - result = -ENODEV; - goto end; - } - - progress++; - - /* - * [2] Check the blacklist - */ - if (acpi_blacklisted()) { - result = -ENODEV; - goto end; - } - - progress++; - - /* - * [3] Get a separate copy of the FADT for use by other drivers. - */ - status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to get the FADT\n"); - result = -ENODEV; - goto end; - } - - progress++; - - /* - * [4] Enable the ACPI Core Subsystem. - */ - status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n"); - result = -ENODEV; - goto end; - } - - printk(KERN_INFO PREFIX "Interpreter enabled\n"); - - progress++; - - /* - * [5] Get the system interrupt model and evaluate \_PIC. - */ - result = acpi_bus_init_irq(); - if (0 != result) - goto end; - - progress++; - - /* - * [6] Register for all standard device notifications. - */ - status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to register for device notifications\n"); - result = -ENODEV; - goto end; - } - - progress++; - - /* - * [7] Create the root device. - */ - result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, - ACPI_BUS_TYPE_SYSTEM); - if (0 != result) - goto end; - - progress++; - - /* - * [8] Create the root file system. - */ - acpi_device_dir(acpi_root) = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL); - if (!acpi_root) { - result = -ENODEV; - goto end; - } - acpi_root_dir = acpi_device_dir(acpi_root); - - progress++; - - /* - * [9] Install drivers required for proper enumeration of the - * ACPI namespace. - */ - acpi_system_init(); /* ACPI System */ - acpi_power_init(); /* ACPI Bus Power Management */ -#ifdef CONFIG_ACPI_EC - acpi_ec_init(); /* ACPI Embedded Controller */ -#endif -#ifdef CONFIG_ACPI_PCI - acpi_pci_link_init(); /* ACPI PCI Interrupt Link */ - acpi_pci_root_init(); /* ACPI PCI Root Bridge */ -#endif - progress++; - - /* - * [10] Enumerate devices in the ACPI namespace. - */ - result = acpi_bus_scan_fixed(acpi_root); - if (0 != result) - goto end; - result = acpi_bus_scan(acpi_root); - if (0 != result) - goto end; - -end: - /* - * Clean up if anything went awry. - */ - if (0 != result) { - switch (progress) { - case 10: - case 9: remove_proc_entry("ACPI", NULL); - case 8: acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL); - case 7: acpi_remove_notify_handler(ACPI_ROOT_OBJECT, - ACPI_SYSTEM_NOTIFY, &acpi_bus_notify); - case 6: - case 5: - case 4: - case 3: - case 2: acpi_terminate(); - case 1: - case 0: - default: return_VALUE(-ENODEV); - } - } - - return_VALUE(0); -} - - -static void __exit -acpi_bus_exit (void) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_bus_exit"); - - status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, - ACPI_SYSTEM_NOTIFY, acpi_bus_notify); - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - -#ifdef CONFIG_ACPI_PCI - acpi_pci_root_exit(); - acpi_pci_link_exit(); -#endif -#ifdef CONFIG_ACPI_EC - acpi_ec_exit(); -#endif - acpi_power_exit(); - acpi_system_exit(); - - acpi_bus_remove(acpi_root, ACPI_BUS_REMOVAL_NORMAL); - - remove_proc_entry(ACPI_BUS_FILE_ROOT, NULL); - - status = acpi_terminate(); - if (ACPI_FAILURE(status)) - printk(KERN_ERR PREFIX "Unable to terminate the ACPI Interpreter\n"); - else - printk(KERN_ERR PREFIX "Interpreter disabled\n"); - - return_VOID; -} - - -int __init -acpi_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_init"); - - memset(&acpi_fadt, 0, sizeof(FADT_DESCRIPTOR)); - - printk(KERN_INFO PREFIX "Subsystem revision %08x\n", - ACPI_CA_VERSION); - - /* Initial core debug level excludes drivers, so include them now */ - acpi_set_debug(ACPI_DEBUG_LOW); - - if (acpi_disabled) { - printk(KERN_INFO PREFIX "Disabled via command line (acpi=off)\n"); - return -ENODEV; - } - -#ifdef CONFIG_PM - if (PM_IS_ACTIVE()) { - printk(KERN_INFO PREFIX "APM is already active, exiting\n"); - return -ENODEV; - } -#endif - - result = acpi_bus_init(); - if (0 != result) - return_VALUE(result); - -#ifdef CONFIG_PM - pm_active = 1; -#endif - - return_VALUE(0); -} - - -void __exit -acpi_exit (void) -{ - ACPI_FUNCTION_TRACE("acpi_exit"); - -#ifdef CONFIG_PM - pm_active = 0; -#endif - - acpi_bus_exit(); - - return_VOID; -} - - -int __init -acpi_setup(char *str) -{ - while (str && *str) { - if (strncmp(str, "off", 3) == 0) - acpi_disabled = 1; - str = strchr(str, ','); - if (str) - str += strspn(str, ", \t"); - } - return 1; -} - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -subsys_initcall(acpi_init); -#endif - -__setup("acpi=", acpi_setup); - diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c --- a/drivers/acpi/button.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,420 +0,0 @@ -/* - * acpi_button.c - ACPI Button Driver ($Revision: 25 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_BUTTON_COMPONENT -ACPI_MODULE_NAME ("acpi_button") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - - -int acpi_button_add (struct acpi_device *device); -int acpi_button_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_button_driver = { - name: ACPI_BUTTON_DRIVER_NAME, - class: ACPI_BUTTON_CLASS, - ids: "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", - ops: { - add: acpi_button_add, - remove: acpi_button_remove, - }, -}; - -struct acpi_button { - acpi_handle handle; - struct acpi_device *device; /* Fixed button kludge */ - u8 type; - unsigned long pushed; -}; - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -static struct proc_dir_entry *acpi_button_dir = NULL; - - -static int -acpi_button_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_button *button = (struct acpi_button *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_button_read_info"); - - if (!button || !button->device) - goto end; - - p += sprintf(p, "type: %s\n", - acpi_device_name(button->device)); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_button_add_fs ( - struct acpi_device *device) -{ - static struct proc_dir_entry *power_entry; - static struct proc_dir_entry *sleep_entry; - static struct proc_dir_entry *lid_entry; - struct proc_dir_entry *entry = NULL; - struct acpi_button *button = NULL; - - ACPI_FUNCTION_TRACE("acpi_button_add_fs"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - button = acpi_driver_data(device); - - if (!acpi_button_dir) { - acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); - if (!acpi_button_dir) - return_VALUE(-ENODEV); - } - - switch (button->type) { - case ACPI_BUTTON_TYPE_POWER: - case ACPI_BUTTON_TYPE_POWERF: - if (!power_entry) - power_entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, - acpi_button_dir); - entry = power_entry; - break; - case ACPI_BUTTON_TYPE_SLEEP: - case ACPI_BUTTON_TYPE_SLEEPF: - if (!sleep_entry) - sleep_entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, - acpi_button_dir); - entry = sleep_entry; - break; - case ACPI_BUTTON_TYPE_LID: - if (!lid_entry) - lid_entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, - acpi_button_dir); - entry = lid_entry; - break; - } - - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - - /* 'info' [R] */ - entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_BUTTON_FILE_INFO)); - else { - entry->read_proc = acpi_button_read_info; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_button_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); - - if (!acpi_button_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_button_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -void -acpi_button_notify ( - acpi_handle handle, - u32 event, - void *data) -{ - struct acpi_button *button = (struct acpi_button *) data; - - ACPI_FUNCTION_TRACE("acpi_button_notify"); - - if (!button || !button->device) - return_VOID; - - switch (event) { - case ACPI_BUTTON_NOTIFY_STATUS: - acpi_bus_generate_event(button->device, event, ++button->pushed); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return_VOID; -} - - -acpi_status -acpi_button_notify_fixed ( - void *data) -{ - struct acpi_button *button = (struct acpi_button *) data; - - ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); - - if (!button) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); - - return_ACPI_STATUS(AE_OK); -} - - -int -acpi_button_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_button *button = NULL; - - ACPI_FUNCTION_TRACE("acpi_button_add"); - - if (!device) - return_VALUE(-EINVAL); - - button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL); - if (!button) - return_VALUE(-ENOMEM); - memset(button, 0, sizeof(struct acpi_button)); - - button->device = device; - button->handle = device->handle; - acpi_driver_data(device) = button; - - /* - * Determine the button type (via hid), as fixed-feature buttons - * need to be handled a bit differently than generic-space. - */ - if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) { - button->type = ACPI_BUTTON_TYPE_POWER; - sprintf(acpi_device_name(device), "%s", - ACPI_BUTTON_DEVICE_NAME_POWER); - sprintf(acpi_device_class(device), "%s/%s", - ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); - } - else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) { - button->type = ACPI_BUTTON_TYPE_POWERF; - sprintf(acpi_device_name(device), "%s", - ACPI_BUTTON_DEVICE_NAME_POWERF); - sprintf(acpi_device_class(device), "%s/%s", - ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); - } - else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) { - button->type = ACPI_BUTTON_TYPE_SLEEP; - sprintf(acpi_device_name(device), "%s", - ACPI_BUTTON_DEVICE_NAME_SLEEP); - sprintf(acpi_device_class(device), "%s/%s", - ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); - } - else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) { - button->type = ACPI_BUTTON_TYPE_SLEEPF; - sprintf(acpi_device_name(device), "%s", - ACPI_BUTTON_DEVICE_NAME_SLEEPF); - sprintf(acpi_device_class(device), "%s/%s", - ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); - } - else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) { - button->type = ACPI_BUTTON_TYPE_LID; - sprintf(acpi_device_name(device), "%s", - ACPI_BUTTON_DEVICE_NAME_LID); - sprintf(acpi_device_class(device), "%s/%s", - ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); - } - else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported hid [%s]\n", - acpi_device_hid(device))); - result = -ENODEV; - goto end; - } - - result = acpi_button_add_fs(device); - if (0 != result) - goto end; - - switch (button->type) { - case ACPI_BUTTON_TYPE_POWERF: - status = acpi_install_fixed_event_handler ( - ACPI_EVENT_POWER_BUTTON, - acpi_button_notify_fixed, - button); - break; - case ACPI_BUTTON_TYPE_SLEEPF: - status = acpi_install_fixed_event_handler ( - ACPI_EVENT_SLEEP_BUTTON, - acpi_button_notify_fixed, - button); - break; - default: - status = acpi_install_notify_handler ( - button->handle, - ACPI_DEVICE_NOTIFY, - acpi_button_notify, - button); - break; - } - - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); - result = -ENODEV; - goto end; - } - - printk(KERN_INFO PREFIX "%s [%s]\n", - acpi_device_name(device), acpi_device_bid(device)); - -end: - if (0 != result) { - acpi_button_remove_fs(device); - kfree(button); - } - - return_VALUE(result); -} - - -int -acpi_button_remove (struct acpi_device *device, int type) -{ - acpi_status status = 0; - struct acpi_button *button = NULL; - - ACPI_FUNCTION_TRACE("acpi_button_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - button = acpi_driver_data(device); - - /* Unregister for device notifications. */ - switch (button->type) { - case ACPI_BUTTON_TYPE_POWERF: - status = acpi_remove_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, acpi_button_notify_fixed); - break; - case ACPI_BUTTON_TYPE_SLEEPF: - status = acpi_remove_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, acpi_button_notify_fixed); - break; - default: - status = acpi_remove_notify_handler(button->handle, - ACPI_DEVICE_NOTIFY, acpi_button_notify); - break; - } - - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - - acpi_button_remove_fs(device); - - kfree(button); - - return_VALUE(0); -} - - -static int __init -acpi_button_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_button_init"); - - result = acpi_bus_register_driver(&acpi_button_driver); - if (0 > result) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -static void __exit -acpi_button_exit (void) -{ - ACPI_FUNCTION_TRACE("acpi_button_exit"); - - acpi_bus_unregister_driver(&acpi_button_driver); - - return_VOID; -} - - -module_init(acpi_button_init); -module_exit(acpi_button_exit); diff -Nru a/drivers/acpi/debugger/Makefile b/drivers/acpi/debugger/Makefile --- a/drivers/acpi/debugger/Makefile Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,11 +0,0 @@ -# -# Makefile for all Linux ACPI interpreter subdirectories -# - -O_TARGET := $(notdir $(CURDIR)).o - -obj-$(CONFIG_ACPI_INTERPRETER) := $(patsubst %.c,%.o,$(wildcard *.c)) - -EXTRA_CFLAGS += $(ACPI_CFLAGS) - -include $(TOPDIR)/Rules.make diff -Nru a/drivers/acpi/debugger/dbcmds.c b/drivers/acpi/debugger/dbcmds.c --- a/drivers/acpi/debugger/dbcmds.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1112 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbcmds - debug commands and output routines - * $Revision: 83 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acdispat.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acevents.h" -#include "acdebug.h" -#include "acresrc.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbcmds") - - -/* - * Arguments for the Objects command - * These object types map directly to the ACPI_TYPES - */ - -static ARGUMENT_INFO acpi_db_object_types [] = -{ {"ANY"}, - {"NUMBERS"}, - {"STRINGS"}, - {"BUFFERS"}, - {"PACKAGES"}, - {"FIELDS"}, - {"DEVICES"}, - {"EVENTS"}, - {"METHODS"}, - {"MUTEXES"}, - {"REGIONS"}, - {"POWERRESOURCES"}, - {"PROCESSORS"}, - {"THERMALZONES"}, - {"BUFFERFIELDS"}, - {"DDBHANDLES"}, - {NULL} /* Must be null terminated */ -}; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_for_references - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Check if this namespace object refers to the target object - * that is passed in as the context value. - * - * Note: Currently doesn't check subobjects within the Node's object - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_for_references ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_operand_object *obj_desc = (acpi_operand_object *) context; - acpi_namespace_node *node = (acpi_namespace_node *) obj_handle; - - - /* Check for match against the namespace node itself */ - - if (node == (void *) obj_desc) { - acpi_os_printf ("Object is a Node [%4.4s]\n", node->name.ascii); - } - - /* Check for match against the object attached to the node */ - - if (acpi_ns_get_attached_object (node) == obj_desc) { - acpi_os_printf ("Reference at Node->Object %p [%4.4s]\n", node, node->name.ascii); - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_find_references - * - * PARAMETERS: Object_arg - String with hex value of the object - * - * RETURN: None - * - * DESCRIPTION: Search namespace for all references to the input object - * - ******************************************************************************/ - -void -acpi_db_find_references ( - NATIVE_CHAR *object_arg) -{ - acpi_operand_object *obj_desc; - - - /* Convert string to object pointer */ - - obj_desc = ACPI_TO_POINTER (ACPI_STRTOUL (object_arg, NULL, 16)); - - /* Search all nodes in namespace */ - - (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_for_references, (void *) obj_desc, NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_locks - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display information about internal mutexes. - * - ******************************************************************************/ - -void -acpi_db_display_locks (void) -{ - u32 i; - - - for (i = 0; i < MAX_MTX; i++) { - acpi_os_printf ("%26s : %s\n", acpi_ut_get_mutex_name (i), - acpi_gbl_acpi_mutex_info[i].owner_id == ACPI_MUTEX_NOT_ACQUIRED - ? "Locked" : "Unlocked"); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_table_info - * - * PARAMETERS: Table_arg - String with name of table to be displayed - * - * RETURN: None - * - * DESCRIPTION: Display information about loaded tables. Current - * implementation displays all loaded tables. - * - ******************************************************************************/ - -void -acpi_db_display_table_info ( - NATIVE_CHAR *table_arg) -{ - u32 i; - - - for (i = 0; i < NUM_ACPI_TABLES; i++) { - if (acpi_gbl_acpi_tables[i].pointer) { - acpi_os_printf ("%s at %p length %X\n", acpi_gbl_acpi_table_data[i].name, - acpi_gbl_acpi_tables[i].pointer, acpi_gbl_acpi_tables[i].length); - } - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_unload_acpi_table - * - * PARAMETERS: Table_arg - Name of the table to be unloaded - * Instance_arg - Which instance of the table to unload (if - * there are multiple tables of the same type) - * - * RETURN: Nonde - * - * DESCRIPTION: Unload an ACPI table. - * Instance is not implemented - * - ******************************************************************************/ - -void -acpi_db_unload_acpi_table ( - NATIVE_CHAR *table_arg, - NATIVE_CHAR *instance_arg) -{ - u32 i; - acpi_status status; - - - /* Search all tables for the target type */ - - for (i = 0; i < NUM_ACPI_TABLES; i++) { - if (!ACPI_STRNCMP (table_arg, acpi_gbl_acpi_table_data[i].signature, - acpi_gbl_acpi_table_data[i].sig_length)) { - /* Found the table, unload it */ - - status = acpi_unload_table (i); - if (ACPI_SUCCESS (status)) { - acpi_os_printf ("[%s] unloaded and uninstalled\n", table_arg); - } - else { - acpi_os_printf ("%s, while unloading [%s]\n", - acpi_format_exception (status), table_arg); - } - - return; - } - } - - acpi_os_printf ("Unknown table type [%s]\n", table_arg); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_breakpoint - * - * PARAMETERS: Location - AML offset of breakpoint - * Walk_state - Current walk info - * Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Set a breakpoint in a control method at the specified - * AML offset - * - ******************************************************************************/ - -void -acpi_db_set_method_breakpoint ( - NATIVE_CHAR *location, - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u32 address; - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - /* Get and verify the breakpoint address */ - - address = ACPI_STRTOUL (location, NULL, 16); - if (address <= op->common.aml_offset) { - acpi_os_printf ("Breakpoint %X is beyond current address %X\n", address, op->common.aml_offset); - } - - /* Save breakpoint in current walk */ - - walk_state->user_breakpoint = address; - acpi_os_printf ("Breakpoint set at AML offset %X\n", address); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_call_breakpoint - * - * PARAMETERS: Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Set a breakpoint in a control method at the specified - * AML offset - * - ******************************************************************************/ - -void -acpi_db_set_method_call_breakpoint ( - acpi_parse_object *op) -{ - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - - acpi_gbl_step_to_next_call = TRUE; -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_disassemble_aml - * - * PARAMETERS: Statements - Number of statements to disassemble - * Op - Current Op (from parse walk) - * - * RETURN: None - * - * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number - * of statements specified. - * - ******************************************************************************/ - -void -acpi_db_disassemble_aml ( - NATIVE_CHAR *statements, - acpi_parse_object *op) -{ - u32 num_statements = 8; - - - if (!op) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - if (statements) { - num_statements = ACPI_STRTOUL (statements, NULL, 0); - } - - acpi_db_display_op (NULL, op, num_statements); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_namespace - * - * PARAMETERS: Start_arg - Node to begin namespace dump - * Depth_arg - Maximum tree depth to be dumped - * - * RETURN: None - * - * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed - * with type and other information. - * - ******************************************************************************/ - -void -acpi_db_dump_namespace ( - NATIVE_CHAR *start_arg, - NATIVE_CHAR *depth_arg) -{ - acpi_handle subtree_entry = acpi_gbl_root_node; - u32 max_depth = ACPI_UINT32_MAX; - - - /* No argument given, just start at the root and dump entire namespace */ - - if (start_arg) { - /* Check if numeric argument, must be a Node */ - - if ((start_arg[0] >= 0x30) && (start_arg[0] <= 0x39)) { - subtree_entry = ACPI_TO_POINTER (ACPI_STRTOUL (start_arg, NULL, 16)); - if (!acpi_os_readable (subtree_entry, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Address %p is invalid in this address space\n", subtree_entry); - return; - } - - if (ACPI_GET_DESCRIPTOR_TYPE (subtree_entry) != ACPI_DESC_TYPE_NAMED) { - acpi_os_printf ("Address %p is not a valid Named object\n", subtree_entry); - return; - } - } - - /* Alpha argument */ - - else { - /* The parameter is a name string that must be resolved to a Named obj*/ - - subtree_entry = acpi_db_local_ns_lookup (start_arg); - if (!subtree_entry) { - subtree_entry = acpi_gbl_root_node; - } - } - - /* Now we can check for the depth argument */ - - if (depth_arg) { - max_depth = ACPI_STRTOUL (depth_arg, NULL, 0); - } - } - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - acpi_os_printf ("ACPI Namespace (from %p subtree):\n", subtree_entry); - - /* Display the subtree */ - - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, ACPI_UINT32_MAX, subtree_entry); - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_namespace_by_owner - * - * PARAMETERS: Owner_arg - Owner ID whose nodes will be displayed - * Depth_arg - Maximum tree depth to be dumped - * - * RETURN: None - * - * DESCRIPTION: Dump elements of the namespace that are owned by the Owner_id. - * - ******************************************************************************/ - -void -acpi_db_dump_namespace_by_owner ( - NATIVE_CHAR *owner_arg, - NATIVE_CHAR *depth_arg) -{ - acpi_handle subtree_entry = acpi_gbl_root_node; - u32 max_depth = ACPI_UINT32_MAX; - u16 owner_id; - - - owner_id = (u16) ACPI_STRTOUL (owner_arg, NULL, 0); - - /* Now we can check for the depth argument */ - - if (depth_arg) { - max_depth = ACPI_STRTOUL (depth_arg, NULL, 0); - } - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - acpi_os_printf ("ACPI Namespace by owner %X:\n", owner_id); - - /* Display the subtree */ - - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, owner_id, subtree_entry); - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_send_notify - * - * PARAMETERS: Name - Name of ACPI object to send the notify to - * Value - Value of the notify to send. - * - * RETURN: None - * - * DESCRIPTION: Send an ACPI notification. The value specified is sent to the - * named object as an ACPI notify. - * - ******************************************************************************/ - -void -acpi_db_send_notify ( - NATIVE_CHAR *name, - u32 value) -{ - acpi_namespace_node *node; - acpi_status status; - - - /* Translate name to an Named object */ - - node = acpi_db_local_ns_lookup (name); - if (!node) { - return; - } - - /* Decode Named object type */ - - switch (node->type) { - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_THERMAL: - - /* Send the notify */ - - status = acpi_ev_queue_notify_request (node, value); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not queue notify\n"); - } - break; - - default: - acpi_os_printf ("Named object is not a device or a thermal object\n"); - break; - } - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_method_data - * - * PARAMETERS: Type_arg - L for local, A for argument - * Index_arg - which one - * Value_arg - Value to set. - * - * RETURN: None - * - * DESCRIPTION: Set a local or argument for the running control method. - * NOTE: only object supported is Number. - * - ******************************************************************************/ - -void -acpi_db_set_method_data ( - NATIVE_CHAR *type_arg, - NATIVE_CHAR *index_arg, - NATIVE_CHAR *value_arg) -{ - NATIVE_CHAR type; - u32 index; - u32 value; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - acpi_status status; - - - /* Validate Type_arg */ - - ACPI_STRUPR (type_arg); - type = type_arg[0]; - if ((type != 'L') && - (type != 'A')) { - acpi_os_printf ("Invalid SET operand: %s\n", type_arg); - return; - } - - /* Get the index and value */ - - index = ACPI_STRTOUL (index_arg, NULL, 16); - value = ACPI_STRTOUL (value_arg, NULL, 16); - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - - /* Create and initialize the new object */ - - obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); - if (!obj_desc) { - acpi_os_printf ("Could not create an internal object\n"); - return; - } - - obj_desc->integer.value = value; - - - /* Store the new object into the target */ - - switch (type) { - case 'A': - - /* Set a method argument */ - - if (index > MTH_MAX_ARG) { - acpi_os_printf ("Arg%d - Invalid argument name\n", index); - return; - } - - status = acpi_ds_store_object_to_local (AML_ARG_OP, index, obj_desc, walk_state); - if (ACPI_FAILURE (status)) { - return; - } - - obj_desc = walk_state->arguments[index].object; - - acpi_os_printf ("Arg%d: ", index); - acpi_db_display_internal_object (obj_desc, walk_state); - break; - - case 'L': - - /* Set a method local */ - - if (index > MTH_MAX_LOCAL) { - acpi_os_printf ("Local%d - Invalid local variable name\n", index); - return; - } - - status = acpi_ds_store_object_to_local (AML_LOCAL_OP, index, obj_desc, walk_state); - if (ACPI_FAILURE (status)) { - return; - } - - obj_desc = walk_state->local_variables[index].object; - - acpi_os_printf ("Local%d: ", index); - acpi_db_display_internal_object (obj_desc, walk_state); - break; - - default: - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_for_specific_objects - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Display short info about objects in the namespace - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_for_specific_objects ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_operand_object *obj_desc; - acpi_status status; - acpi_buffer buffer; - - - obj_desc = acpi_ns_get_attached_object ((acpi_namespace_node *) obj_handle); - - /* Get and display the full pathname to this object */ - - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname (obj_handle, &buffer); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle); - return (AE_OK); - } - - acpi_os_printf ("%32s", buffer.pointer); - ACPI_MEM_FREE (buffer.pointer); - - - /* Display short information about the object */ - - if (obj_desc) { - switch (obj_desc->common.type) { - case ACPI_TYPE_METHOD: - acpi_os_printf (" #Args %d Concurrency %X", obj_desc->method.param_count, obj_desc->method.concurrency); - break; - - case ACPI_TYPE_INTEGER: - acpi_os_printf (" Value %X", obj_desc->integer.value); - break; - - case ACPI_TYPE_STRING: - acpi_os_printf (" \"%s\"", obj_desc->string.pointer); - break; - - case ACPI_TYPE_REGION: - acpi_os_printf (" Space_id %X Address %X Length %X", obj_desc->region.space_id, obj_desc->region.address, obj_desc->region.length); - break; - - case ACPI_TYPE_PACKAGE: - acpi_os_printf (" #Elements %X", obj_desc->package.count); - break; - - case ACPI_TYPE_BUFFER: - acpi_os_printf (" Length %X", obj_desc->buffer.length); - break; - - default: - /* Ignore other object types */ - break; - } - } - - acpi_os_printf ("\n"); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_objects - * - * PARAMETERS: Obj_type_arg - Type of object to display - * Display_count_arg - Max depth to display - * - * RETURN: None - * - * DESCRIPTION: Display objects in the namespace of the requested type - * - ******************************************************************************/ - -acpi_status -acpi_db_display_objects ( - NATIVE_CHAR *obj_type_arg, - NATIVE_CHAR *display_count_arg) -{ - acpi_object_type type; - - - /* Get the object type */ - - type = acpi_db_match_argument (obj_type_arg, acpi_db_object_types); - if (type == ACPI_TYPE_NOT_FOUND) { - acpi_os_printf ("Invalid or unsupported argument\n"); - return (AE_OK); - } - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - acpi_os_printf ("Objects of type [%s] defined in the current ACPI Namespace: \n", acpi_ut_get_type_name (type)); - - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - - /* Walk the namespace from the root */ - - (void) acpi_walk_namespace (type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_for_specific_objects, (void *) &type, NULL); - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_walk_and_match_name - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Find a particular name/names within the namespace. Wildcards - * are supported -- '?' matches any character. - * - ******************************************************************************/ - -acpi_status -acpi_db_walk_and_match_name ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_status status; - NATIVE_CHAR *requested_name = (NATIVE_CHAR *) context; - u32 i; - acpi_buffer buffer; - - - /* Check for a name match */ - - for (i = 0; i < 4; i++) { - /* Wildcard support */ - - if ((requested_name[i] != '?') && - (requested_name[i] != ((acpi_namespace_node *) obj_handle)->name.ascii[i])) { - /* No match, just exit */ - - return (AE_OK); - } - } - - - /* Get the full pathname to this object */ - - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname (obj_handle, &buffer); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could Not get pathname for object %p\n", obj_handle); - } - else { - acpi_os_printf ("%32s (%p) - %s\n", buffer.pointer, obj_handle, - acpi_ut_get_type_name (((acpi_namespace_node *) obj_handle)->type)); - ACPI_MEM_FREE (buffer.pointer); - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_find_name_in_namespace - * - * PARAMETERS: Name_arg - The 4-character ACPI name to find. - * wildcards are supported. - * - * RETURN: None - * - * DESCRIPTION: Search the namespace for a given name (with wildcards) - * - ******************************************************************************/ - -acpi_status -acpi_db_find_name_in_namespace ( - NATIVE_CHAR *name_arg) -{ - - if (ACPI_STRLEN (name_arg) > 4) { - acpi_os_printf ("Name must be no longer than 4 characters\n"); - return (AE_OK); - } - - /* Walk the namespace from the root */ - - (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_walk_and_match_name, name_arg, NULL); - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_scope - * - * PARAMETERS: Name - New scope path - * - * RETURN: Status - * - * DESCRIPTION: Set the "current scope" as maintained by this utility. - * The scope is used as a prefix to ACPI paths. - * - ******************************************************************************/ - -void -acpi_db_set_scope ( - NATIVE_CHAR *name) -{ - acpi_status status; - acpi_namespace_node *node; - - - if (!name || name[0] == 0) { - acpi_os_printf ("Current scope: %s\n", acpi_gbl_db_scope_buf); - return; - } - - acpi_db_prep_namestring (name); - - - if (name[0] == '\\') { - /* Validate new scope from the root */ - - status = acpi_ns_get_node_by_path (name, acpi_gbl_root_node, ACPI_NS_NO_UPSEARCH, &node); - if (ACPI_FAILURE (status)) { - goto error_exit; - } - - ACPI_STRCPY (acpi_gbl_db_scope_buf, name); - ACPI_STRCAT (acpi_gbl_db_scope_buf, "\\"); - } - else { - /* Validate new scope relative to old scope */ - - status = acpi_ns_get_node_by_path (name, acpi_gbl_db_scope_node, ACPI_NS_NO_UPSEARCH, &node); - if (ACPI_FAILURE (status)) { - goto error_exit; - } - - ACPI_STRCAT (acpi_gbl_db_scope_buf, name); - ACPI_STRCAT (acpi_gbl_db_scope_buf, "\\"); - } - - acpi_gbl_db_scope_node = node; - acpi_os_printf ("New scope: %s\n", acpi_gbl_db_scope_buf); - return; - - -error_exit: - - acpi_os_printf ("Could not attach scope: %s, %s\n", name, acpi_format_exception (status)); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_resources - * - * PARAMETERS: Object_arg - String with hex value of the object - * - * RETURN: None - * - * DESCRIPTION: - * - ******************************************************************************/ - -void -acpi_db_display_resources ( - NATIVE_CHAR *object_arg) -{ -#if ACPI_MACHINE_WIDTH != 16 - - acpi_operand_object *obj_desc; - acpi_status status; - acpi_buffer return_obj; - - - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - acpi_dbg_level |= ACPI_LV_RESOURCES; - - /* Convert string to object pointer */ - - obj_desc = ACPI_TO_POINTER (ACPI_STRTOUL (object_arg, NULL, 16)); - - /* Prepare for a return object of arbitrary size */ - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - /* _PRT */ - - acpi_os_printf ("Evaluating _PRT\n"); - - status = acpi_evaluate_object (obj_desc, "_PRT", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _PRT: %s\n", acpi_format_exception (status)); - goto get_crs; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_irq_routing_table (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Get_irq_routing_table failed: %s\n", acpi_format_exception (status)); - } - - else { - acpi_rs_dump_irq_list ((u8 *) acpi_gbl_db_buffer); - } - - - /* _CRS */ - -get_crs: - acpi_os_printf ("Evaluating _CRS\n"); - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_evaluate_object (obj_desc, "_CRS", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _CRS: %s\n", acpi_format_exception (status)); - goto get_prs; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_current_resources (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Acpi_get_current_resources failed: %s\n", acpi_format_exception (status)); - goto get_prs; - } - - else { - acpi_rs_dump_resource_list (ACPI_CAST_PTR (acpi_resource, acpi_gbl_db_buffer)); - } - - status = acpi_set_current_resources (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Acpi_set_current_resources failed: %s\n", acpi_format_exception (status)); - goto get_prs; - } - - - /* _PRS */ - -get_prs: - acpi_os_printf ("Evaluating _PRS\n"); - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_evaluate_object (obj_desc, "_PRS", NULL, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not obtain _PRS: %s\n", acpi_format_exception (status)); - goto cleanup; - } - - return_obj.pointer = acpi_gbl_db_buffer; - return_obj.length = ACPI_DEBUG_BUFFER_SIZE; - - status = acpi_get_possible_resources (obj_desc, &return_obj); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Acpi_get_possible_resources failed: %s\n", acpi_format_exception (status)); - } - - else { - acpi_rs_dump_resource_list (ACPI_CAST_PTR (acpi_resource, acpi_gbl_db_buffer)); - } - - -cleanup: - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - return; -#endif - -} - - -typedef struct -{ - u32 nodes; - u32 objects; -} ACPI_INTEGRITY_INFO; - -/******************************************************************************* - * - * FUNCTION: Acpi_db_integrity_walk - * - * PARAMETERS: Callback from Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Examine one NS node for valid values. - * - ******************************************************************************/ - -acpi_status -acpi_db_integrity_walk ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - ACPI_INTEGRITY_INFO *info = (ACPI_INTEGRITY_INFO *) context; - acpi_namespace_node *node = (acpi_namespace_node *) obj_handle; - acpi_operand_object *object; - - - info->nodes++; - if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) { - acpi_os_printf ("Invalid Descriptor Type for Node %p, Type = %X\n", - node, ACPI_GET_DESCRIPTOR_TYPE (node)); - } - - if (node->type > INTERNAL_TYPE_MAX) { - acpi_os_printf ("Invalid Object Type for Node %p, Type = %X\n", - node, node->type); - } - - if (!acpi_ut_valid_acpi_name (node->name.integer)) { - acpi_os_printf ("Invalid Acpi_name for Node %p\n", node); - } - - object = acpi_ns_get_attached_object (node); - if (object) { - info->objects++; - if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) { - acpi_os_printf ("Invalid Descriptor Type for Object %p, Type = %X\n", - object, ACPI_GET_DESCRIPTOR_TYPE (object)); - } - } - - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_check_integrity - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Check entire namespace for data structure integrity - * - ******************************************************************************/ - -void -acpi_db_check_integrity (void) -{ - ACPI_INTEGRITY_INFO info = {0,0}; - - /* Search all nodes in namespace */ - - (void) acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_db_integrity_walk, (void *) &info, NULL); - - acpi_os_printf ("Verified %d namespace nodes with %d Objects\n", info.nodes, info.objects); - -} - -#endif /* ENABLE_DEBUGGER */ diff -Nru a/drivers/acpi/debugger/dbdisasm.c b/drivers/acpi/debugger/dbdisasm.c --- a/drivers/acpi/debugger/dbdisasm.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,706 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisasm - parser op tree display routines - * $Revision: 66 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbdisasm") - - -#define BLOCK_PAREN 1 -#define BLOCK_BRACE 2 -#define DB_NO_OP_INFO " [%2.2d] " -#define DB_FULL_OP_INFO "%5.5X #%4.4hX [%2.2d] " - - -NATIVE_CHAR *acpi_gbl_db_disasm_indent = "...."; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_block_type - * - * PARAMETERS: Op - Object to be examined - * - * RETURN: Status - * - * DESCRIPTION: Type of block for this op (parens or braces) - * - ******************************************************************************/ - -u32 -acpi_db_block_type ( - acpi_parse_object *op) -{ - - switch (op->common.aml_opcode) { - case AML_METHOD_OP: - return (BLOCK_BRACE); - - default: - break; - } - - return (BLOCK_PAREN); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_display_object_pathname - * - * PARAMETERS: Op - Object whose pathname is to be obtained - * - * RETURN: Status - * - * DESCRIPTION: Diplay the pathname associated with a named object. Two - * versions. One searches the parse tree (for parser-only - * applications suchas Acpi_dump), and the other searches the - * ACPI namespace (the parse tree is probably deleted) - * - ******************************************************************************/ - -#ifdef PARSER_ONLY - -acpi_status -acpi_ps_display_object_pathname ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - acpi_parse_object *target_op; - char *name; - - - if (op->common.flags & ACPI_PARSEOP_GENERIC) { - name = op->common.value.name; - if (name[0] == '\\') { - acpi_os_printf (" (Fully Qualified Pathname)"); - return (AE_OK); - } - } - else { - name = (char *) &op->named.name; - } - - /* Search parent tree up to the root if necessary */ - - target_op = acpi_ps_find (op, name, 0, 0); - if (!target_op) { - /* - * Didn't find the name in the parse tree. This may be - * a problem, or it may simply be one of the predefined names - * (such as _OS_). Rather than worry about looking up all - * the predefined names, just display the name as given - */ - acpi_os_printf (" **** Path not found in parse tree"); - } - else { - /* The target was found, print the name and complete path */ - - acpi_os_printf (" (Path "); - acpi_db_display_path (target_op); - acpi_os_printf (")"); - } - - return (AE_OK); -} - -#else - -acpi_status -acpi_ps_display_object_pathname ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - acpi_status status; - acpi_namespace_node *node; - acpi_buffer buffer; - u32 debug_level; - - - /* Save current debug level so we don't get extraneous debug output */ - - debug_level = acpi_dbg_level; - acpi_dbg_level = 0; - - /* Just get the Node out of the Op object */ - - node = op->common.node; - if (!node) { - /* Node not defined in this scope, look it up */ - - status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); - - if (ACPI_FAILURE (status)) { - /* - * We can't get the pathname since the object - * is not in the namespace. This can happen during single - * stepping where a dynamic named object is *about* to be created. - */ - acpi_os_printf (" [Path not found]"); - goto exit; - } - - /* Save it for next time. */ - - op->common.node = node; - } - - /* Convert Named_desc/handle to a full pathname */ - - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_ns_handle_to_pathname (node, &buffer); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("****Could not get pathname****)"); - goto exit; - } - - acpi_os_printf (" (Path %s)", buffer.pointer); - ACPI_MEM_FREE (buffer.pointer); - - -exit: - /* Restore the debug level */ - - acpi_dbg_level = debug_level; - return (status); -} - -#endif - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_op - * - * PARAMETERS: Origin - Starting object - * Num_opcodes - Max number of opcodes to be displayed - * - * RETURN: None - * - * DESCRIPTION: Display parser object and its children - * - ******************************************************************************/ - -void -acpi_db_display_op ( - acpi_walk_state *walk_state, - acpi_parse_object *origin, - u32 num_opcodes) -{ - acpi_parse_object *op = origin; - acpi_parse_object *arg; - acpi_parse_object *depth; - u32 depth_count = 0; - u32 last_depth = 0; - u32 i; - u32 j; - - - if (!op) { - acpi_db_display_opcode (walk_state, op); - return; - } - - - while (op) { - /* Indentation */ - - depth_count = 0; - if (!acpi_gbl_db_opt_verbose) { - depth_count++; - } - - /* Determine the nesting depth of this argument */ - - for (depth = op->common.parent; depth; depth = depth->common.parent) { - arg = acpi_ps_get_arg (depth, 0); - while (arg && arg != origin) { - arg = arg->common.next; - } - - if (arg) { - break; - } - - depth_count++; - } - - /* Open a new block if we are nested further than last time */ - - if (depth_count > last_depth) { - VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth)); - for (i = 0; i < last_depth; i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - if (acpi_db_block_type (op) == BLOCK_PAREN) { - acpi_os_printf ("(\n"); - } - else { - acpi_os_printf ("{\n"); - } - } - - /* Close a block if we are nested less than last time */ - - else if (depth_count < last_depth) { - for (j = last_depth; j >= (depth_count + 1); j--) { - VERBOSE_PRINT ((DB_NO_OP_INFO, (j - 1))); - for (i = 1; i < j; i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - if (acpi_db_block_type (op) == BLOCK_PAREN) { - acpi_os_printf (")\n"); - } - else { - acpi_os_printf ("}\n"); - } - } - } - - /* In verbose mode, print the AML offset, opcode and depth count */ - - VERBOSE_PRINT ((DB_FULL_OP_INFO, (u32) op->common.aml_offset, - op->common.aml_opcode, depth_count)); - - - /* Indent the output according to the depth count */ - - for (i = 0; i < depth_count; i++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - - /* Now print the opcode */ - - acpi_db_display_opcode (walk_state, op); - - /* Resolve a name reference */ - - if ((op->common.aml_opcode == AML_INT_NAMEPATH_OP && op->common.value.name) && - (op->common.parent) && - (acpi_gbl_db_opt_verbose)) { - (void) acpi_ps_display_object_pathname (walk_state, op); - } - - acpi_os_printf ("\n"); - - /* Get the next node in the tree */ - - op = acpi_ps_get_depth_next (origin, op); - last_depth = depth_count; - - num_opcodes--; - if (!num_opcodes) { - op = NULL; - } - } - - /* Close the last block(s) */ - - depth_count = last_depth -1; - for (i = 0; i < last_depth; i++) { - VERBOSE_PRINT ((DB_NO_OP_INFO, last_depth - i)); - for (j = 0; j < depth_count; j++) { - acpi_os_printf ("%s", acpi_gbl_db_disasm_indent); - } - acpi_os_printf ("}\n"); - depth_count--; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_namestring - * - * PARAMETERS: Name - ACPI Name string to store - * - * RETURN: None - * - * DESCRIPTION: Display namestring. Handles prefix characters - * - ******************************************************************************/ - -void -acpi_db_display_namestring ( - NATIVE_CHAR *name) -{ - u32 seg_count; - - - if (!name) { - acpi_os_printf (""); - return; - } - - /* Handle all Scope Prefix operators */ - - while (acpi_ps_is_prefix_char (ACPI_GET8 (name))) { - /* Append prefix character */ - - acpi_os_printf ("%1c", ACPI_GET8 (name)); - name++; - } - - switch (ACPI_GET8 (name)) { - case 0: - seg_count = 0; - break; - - case AML_DUAL_NAME_PREFIX: - seg_count = 2; - name++; - break; - - case AML_MULTI_NAME_PREFIX_OP: - seg_count = (u32) ACPI_GET8 (name + 1); - name += 2; - break; - - default: - seg_count = 1; - break; - } - - while (seg_count) { - /* Append Name segment */ - - acpi_os_printf ("%4.4s", name); - - seg_count--; - if (seg_count) { - /* Not last name, append dot separator */ - - acpi_os_printf ("."); - } - name += ACPI_NAME_SIZE; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_path - * - * PARAMETERS: Op - Named Op whose path is to be constructed - * - * RETURN: None - * - * DESCRIPTION: Walk backwards from current scope and display the name - * of each previous level of scope up to the root scope - * (like "pwd" does with file systems) - * - ******************************************************************************/ - -void -acpi_db_display_path ( - acpi_parse_object *op) -{ - acpi_parse_object *prev; - acpi_parse_object *search; - u32 name; - u8 do_dot = FALSE; - acpi_parse_object *name_path; - const acpi_opcode_info *op_info; - - - /* We are only interested in named objects */ - - op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); - if (!(op_info->flags & AML_NSNODE)) { - return; - } - - if (op_info->flags & AML_CREATE) { - /* Field creation - check for a fully qualified namepath */ - - if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { - name_path = acpi_ps_get_arg (op, 3); - } - else { - name_path = acpi_ps_get_arg (op, 2); - } - - if ((name_path) && - (name_path->common.value.string) && - (name_path->common.value.string[0] == '\\')) { - acpi_db_display_namestring (name_path->common.value.string); - return; - } - } - - prev = NULL; /* Start with Root Node */ - - while (prev != op) { - /* Search upwards in the tree to find scope with "prev" as its parent */ - - search = op; - for (; ;) { - if (search->common.parent == prev) { - break; - } - - /* Go up one level */ - - search = search->common.parent; - } - - if (prev) { - op_info = acpi_ps_get_opcode_info (search->common.aml_opcode); - if (!(op_info->flags & AML_FIELD)) { - /* below root scope, append scope name */ - - if (do_dot) { - /* append dot */ - - acpi_os_printf ("."); - } - - if (op_info->flags & AML_CREATE) { - if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { - name_path = acpi_ps_get_arg (op, 3); - } - else { - name_path = acpi_ps_get_arg (op, 2); - } - - if ((name_path) && - (name_path->common.value.string)) { - acpi_os_printf ("%4.4s", name_path->common.value.string); - } - } - else { - name = acpi_ps_get_name (search); - acpi_os_printf ("%4.4s", &name); - } - - do_dot = TRUE; - } - } - - prev = search; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_opcode - * - * PARAMETERS: Op - Op that is to be printed - * - * RETURN: Status - * - * DESCRIPTION: Store printed op in a Buffer and return its length - * (or -1 if out of space) - * - * NOTE: Terse mode prints out ASL-like code. Verbose mode adds more info. - * - ******************************************************************************/ - -void -acpi_db_display_opcode ( - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u8 *byte_data; - u32 byte_count; - u32 i; - const acpi_opcode_info *op_info = NULL; - u32 name; - - - if (!op) { - acpi_os_printf (""); - return; - } - - /* op and arguments */ - - switch (op->common.aml_opcode) { - case AML_BYTE_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u8) 0x%2.2hX", op->common.value.integer8); - } - else { - acpi_os_printf ("0x%2.2hX", op->common.value.integer8); - } - break; - - - case AML_WORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u16) 0x%4.4hX", op->common.value.integer16); - } - else { - acpi_os_printf ("0x%4.4hX", op->common.value.integer16); - } - break; - - - case AML_DWORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u32) 0x%8.8X", op->common.value.integer32); - } - else { - acpi_os_printf ("0x%8.8X", op->common.value.integer32); - } - break; - - - case AML_QWORD_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("(u64) 0x%8.8X%8.8X", op->common.value.integer64.hi, - op->common.value.integer64.lo); - } - else { - acpi_os_printf ("0x%8.8X%8.8X", op->common.value.integer64.hi, - op->common.value.integer64.lo); - } - break; - - - case AML_STRING_OP: - - if (op->common.value.string) { - acpi_os_printf ("\"%s\"", op->common.value.string); - } - else { - acpi_os_printf ("<\"NULL STRING PTR\">"); - } - break; - - - case AML_INT_STATICSTRING_OP: - - if (op->common.value.string) { - acpi_os_printf ("\"%s\"", op->common.value.string); - } - else { - acpi_os_printf ("\"\""); - } - break; - - - case AML_INT_NAMEPATH_OP: - - acpi_db_display_namestring (op->common.value.name); - break; - - - case AML_INT_NAMEDFIELD_OP: - - acpi_os_printf ("Named_field (Length 0x%8.8X) ", op->common.value.integer32); - break; - - - case AML_INT_RESERVEDFIELD_OP: - - acpi_os_printf ("Reserved_field (Length 0x%8.8X) ", op->common.value.integer32); - break; - - - case AML_INT_ACCESSFIELD_OP: - - acpi_os_printf ("Access_field (Length 0x%8.8X) ", op->common.value.integer32); - break; - - - case AML_INT_BYTELIST_OP: - - if (acpi_gbl_db_opt_verbose) { - acpi_os_printf ("Byte_list (Length 0x%8.8X) ", op->common.value.integer32); - } - else { - acpi_os_printf ("0x%2.2X", op->common.value.integer32); - - byte_count = op->common.value.integer32; - byte_data = op->named.data; - - for (i = 0; i < byte_count; i++) { - acpi_os_printf (", 0x%2.2X", byte_data[i]); - } - } - break; - - - default: - - /* Just get the opcode name and print it */ - - op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); - acpi_os_printf ("%s", op_info->name); - - -#ifndef PARSER_ONLY - if ((op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) && - (walk_state) && - (walk_state->results) && - (walk_state->results->results.num_results)) { - acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]); - } -#endif - break; - } - - if (!op_info) { - /* If there is another element in the list, add a comma */ - - if (op->common.next) { - acpi_os_printf (","); - } - } - - /* - * If this is a named opcode, print the associated name value - */ - op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); - if (op && (op_info->flags & AML_NAMED)) { - name = acpi_ps_get_name (op); - acpi_os_printf (" %4.4s", &name); - - if ((acpi_gbl_db_opt_verbose) && (op->common.aml_opcode != AML_INT_NAMEDFIELD_OP)) { - (void) acpi_ps_display_object_pathname (walk_state, op); - } - } -} - -#endif /* ENABLE_DEBUGGER */ - diff -Nru a/drivers/acpi/debugger/dbdisply.c b/drivers/acpi/debugger/dbdisply.c --- a/drivers/acpi/debugger/dbdisply.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,813 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbdisply - debug display commands - * $Revision: 73 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "amlcode.h" -#include "acdispat.h" -#include "acnamesp.h" -#include "acparser.h" -#include "acinterp.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbdisply") - - -/****************************************************************************** - * - * FUNCTION: Acpi_db_get_pointer - * - * PARAMETERS: Target - Pointer to string to be converted - * - * RETURN: Converted pointer - * - * DESCRIPTION: Convert an ascii pointer value to a real value - * - *****************************************************************************/ - -void * -acpi_db_get_pointer ( - void *target) -{ - void *obj_ptr; - - -#if ACPI_MACHINE_WIDTH == 16 -#include - - /* Have to handle 16-bit pointers of the form segment:offset */ - - if (!sscanf (target, "%p", &obj_ptr)) { - acpi_os_printf ("Invalid pointer: %s\n", target); - return (NULL); - } - -#else - - /* Simple flat pointer */ - - obj_ptr = ACPI_TO_POINTER (ACPI_STRTOUL (target, NULL, 16)); -#endif - - return (obj_ptr); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_parser_descriptor - * - * PARAMETERS: Op - A parser Op descriptor - * - * RETURN: None - * - * DESCRIPTION: Display a formatted parser object - * - ******************************************************************************/ - -void -acpi_db_dump_parser_descriptor ( - acpi_parse_object *op) -{ - const acpi_opcode_info *info; - - - info = acpi_ps_get_opcode_info (op->common.aml_opcode); - - acpi_os_printf ("Parser Op Descriptor:\n"); - acpi_os_printf ("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode); - - ACPI_DEBUG_ONLY_MEMBERS (acpi_os_printf ("%20.20s : %s\n", "Opcode Name", info->name)); - - acpi_os_printf ("%20.20s : %p\n", "Value/Arg_list", op->common.value.arg); - acpi_os_printf ("%20.20s : %p\n", "Parent", op->common.parent); - acpi_os_printf ("%20.20s : %p\n", "Next_op", op->common.next); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_decode_and_display_object - * - * PARAMETERS: Target - String with object to be displayed. Names - * and hex pointers are supported. - * Output_type - Byte, Word, Dword, or Qword (B|W|D|Q) - * - * RETURN: None - * - * DESCRIPTION: Display a formatted ACPI object - * - ******************************************************************************/ - -void -acpi_db_decode_and_display_object ( - NATIVE_CHAR *target, - NATIVE_CHAR *output_type) -{ - void *obj_ptr; - acpi_namespace_node *node; - acpi_operand_object *obj_desc; - u32 display = DB_BYTE_DISPLAY; - NATIVE_CHAR buffer[80]; - acpi_buffer ret_buf; - acpi_status status; - u32 size; - - - if (!target) { - return; - } - - /* Decode the output type */ - - if (output_type) { - ACPI_STRUPR (output_type); - if (output_type[0] == 'W') { - display = DB_WORD_DISPLAY; - } - else if (output_type[0] == 'D') { - display = DB_DWORD_DISPLAY; - } - else if (output_type[0] == 'Q') { - display = DB_QWORD_DISPLAY; - } - } - - ret_buf.length = sizeof (buffer); - ret_buf.pointer = buffer; - - /* Differentiate between a number and a name */ - - if ((target[0] >= 0x30) && (target[0] <= 0x39)) { - obj_ptr = acpi_db_get_pointer (target); - if (!acpi_os_readable (obj_ptr, 16)) { - acpi_os_printf ("Address %p is invalid in this address space\n", obj_ptr); - return; - } - - /* Decode the object type */ - - switch (ACPI_GET_DESCRIPTOR_TYPE (obj_ptr)) { - case ACPI_DESC_TYPE_NAMED: - - /* This is a namespace Node */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Cannot read entire Named object at address %p\n", obj_ptr); - return; - } - - node = obj_ptr; - goto dump_nte; - - - case ACPI_DESC_TYPE_OPERAND: - - /* This is a ACPI OPERAND OBJECT */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_operand_object))) { - acpi_os_printf ("Cannot read entire ACPI object at address %p\n", obj_ptr); - return; - } - - acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX); - acpi_ex_dump_object_descriptor (obj_ptr, 1); - break; - - - case ACPI_DESC_TYPE_PARSER: - - /* This is a Parser Op object */ - - if (!acpi_os_readable (obj_ptr, sizeof (acpi_parse_object))) { - acpi_os_printf ("Cannot read entire Parser object at address %p\n", obj_ptr); - return; - } - - acpi_ut_dump_buffer (obj_ptr, sizeof (acpi_parse_object), display, ACPI_UINT32_MAX); - acpi_db_dump_parser_descriptor ((acpi_parse_object *) obj_ptr); - break; - - - default: - - /* Is not a recognizeable object */ - - size = 16; - if (acpi_os_readable (obj_ptr, 64)) { - size = 64; - } - - /* Just dump some memory */ - - acpi_ut_dump_buffer (obj_ptr, size, display, ACPI_UINT32_MAX); - break; - } - - return; - } - - /* The parameter is a name string that must be resolved to a Named obj */ - - node = acpi_db_local_ns_lookup (target); - if (!node) { - return; - } - - -dump_nte: - /* Now dump the Named obj */ - - status = acpi_get_name (node, ACPI_FULL_PATHNAME, &ret_buf); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not convert name to pathname\n"); - } - - else { - acpi_os_printf ("Object (%p) Pathname: %s\n", node, ret_buf.pointer); - } - - if (!acpi_os_readable (node, sizeof (acpi_namespace_node))) { - acpi_os_printf ("Invalid Named object at address %p\n", node); - return; - } - - acpi_ut_dump_buffer ((void *) node, sizeof (acpi_namespace_node), display, ACPI_UINT32_MAX); - acpi_ex_dump_node (node, 1); - - obj_desc = acpi_ns_get_attached_object (node); - if (obj_desc) { - acpi_os_printf ("\n_attached Object (%p):\n", obj_desc); - if (!acpi_os_readable (obj_desc, sizeof (acpi_operand_object))) { - acpi_os_printf ("Invalid internal ACPI Object at address %p\n", obj_desc); - return; - } - - acpi_ut_dump_buffer ((void *) obj_desc, sizeof (acpi_operand_object), display, ACPI_UINT32_MAX); - acpi_ex_dump_object_descriptor (obj_desc, 1); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_decode_internal_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * - * RETURN: None - * - * DESCRIPTION: Short display of an internal object. Numbers and Strings. - * - ******************************************************************************/ - -void -acpi_db_decode_internal_object ( - acpi_operand_object *obj_desc) -{ - u32 i; - - - if (!obj_desc) { - acpi_os_printf (" Uninitialized\n"); - return; - } - - acpi_os_printf (" %s", acpi_ut_get_type_name (obj_desc->common.type)); - - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: - - acpi_os_printf (" %8.8X%8.8X", ACPI_HIDWORD (obj_desc->integer.value), - ACPI_LODWORD (obj_desc->integer.value)); - break; - - - case ACPI_TYPE_STRING: - - acpi_os_printf ("(%d) \"%.24s", - obj_desc->string.length, obj_desc->string.pointer); - - if (obj_desc->string.length > 24) - { - acpi_os_printf ("..."); - } - else - { - acpi_os_printf ("\""); - } - break; - - - case ACPI_TYPE_BUFFER: - - acpi_os_printf ("(%d)", obj_desc->buffer.length); - for (i = 0; (i < 8) && (i < obj_desc->buffer.length); i++) { - acpi_os_printf (" %2.2X", obj_desc->buffer.pointer[i]); - } - break; - - - default: - /* No additional display for other types */ - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_internal_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Short display of an internal object - * - ******************************************************************************/ - -void -acpi_db_display_internal_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - u8 type; - - - acpi_os_printf ("%p ", obj_desc); - - if (!obj_desc) { - acpi_os_printf ("\n"); - return; - } - - /* Decode the object type */ - - switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) { - case ACPI_DESC_TYPE_PARSER: - - acpi_os_printf (" "); - break; - - - case ACPI_DESC_TYPE_NAMED: - - acpi_os_printf (" Name %4.4s Type-%s", - ((acpi_namespace_node *)obj_desc)->name.ascii, - acpi_ut_get_type_name (((acpi_namespace_node *) obj_desc)->type)); - - if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_ARG) { - acpi_os_printf (" [Method Arg]"); - } - if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_LOCAL) { - acpi_os_printf (" [Method Local]"); - } - break; - - - case ACPI_DESC_TYPE_OPERAND: - - type = obj_desc->common.type; - if (type > INTERNAL_TYPE_MAX) { - acpi_os_printf (" Type %hX [Invalid Type]", type); - return; - } - - /* Decode the ACPI object type */ - - switch (obj_desc->common.type) { - case INTERNAL_TYPE_REFERENCE: - switch (obj_desc->reference.opcode) { - case AML_ZERO_OP: - acpi_os_printf ("[Const] Zero (0) [Null Target]", 0); - break; - - case AML_ONES_OP: - acpi_os_printf ("[Const] Ones (0xFFFFFFFFFFFFFFFF) [No Limit]"); - break; - - case AML_ONE_OP: - acpi_os_printf ("[Const] One (1)"); - break; - - case AML_REVISION_OP: - acpi_os_printf ("[Const] Revision (%X)", ACPI_CA_SUPPORT_LEVEL); - break; - - case AML_LOCAL_OP: - acpi_os_printf ("[Local%d] ", obj_desc->reference.offset); - if (walk_state) { - obj_desc = walk_state->local_variables[obj_desc->reference.offset].object; - acpi_os_printf ("%p", obj_desc); - acpi_db_decode_internal_object (obj_desc); - } - break; - - case AML_ARG_OP: - acpi_os_printf ("[Arg%d] ", obj_desc->reference.offset); - if (walk_state) { - obj_desc = walk_state->arguments[obj_desc->reference.offset].object; - acpi_os_printf ("%p", obj_desc); - acpi_db_decode_internal_object (obj_desc); - } - break; - - case AML_DEBUG_OP: - acpi_os_printf ("[Debug] "); - break; - - case AML_INDEX_OP: - acpi_os_printf ("[Index] "); - acpi_db_decode_internal_object (obj_desc->reference.object); - break; - - default: - break; - - } - break; - - default: - acpi_os_printf (" "); - acpi_os_printf (" "); - acpi_db_decode_internal_object (obj_desc); - break; - } - break; - - - default: - - acpi_os_printf (" "); - break; - } - - acpi_os_printf ("\n"); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_method_info - * - * PARAMETERS: Start_op - Root of the control method parse tree - * - * RETURN: None - * - * DESCRIPTION: Display information about the current method - * - ******************************************************************************/ - -void -acpi_db_display_method_info ( - acpi_parse_object *start_op) -{ - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - acpi_parse_object *root_op; - acpi_parse_object *op; - const acpi_opcode_info *op_info; - u32 num_ops = 0; - u32 num_operands = 0; - u32 num_operators = 0; - u32 num_remaining_ops = 0; - u32 num_remaining_operands = 0; - u32 num_remaining_operators = 0; - u32 num_args; - u32 concurrency; - u8 count_remaining = FALSE; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - num_args = obj_desc->method.param_count; - concurrency = obj_desc->method.concurrency; - - acpi_os_printf ("Currently executing control method is [%4.4s]\n", node->name.ascii); - acpi_os_printf ("%X arguments, max concurrency = %X\n", num_args, concurrency); - - - root_op = start_op; - while (root_op->common.parent) { - root_op = root_op->common.parent; - } - - op = root_op; - - while (op) { - if (op == start_op) { - count_remaining = TRUE; - } - - num_ops++; - if (count_remaining) { - num_remaining_ops++; - } - - /* Decode the opcode */ - - op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); - switch (op_info->class) { - case AML_CLASS_ARGUMENT: - if (count_remaining) { - num_remaining_operands++; - } - - num_operands++; - break; - - case AML_CLASS_UNKNOWN: - /* Bad opcode or ASCII character */ - - continue; - - default: - if (count_remaining) { - num_remaining_operators++; - } - - num_operators++; - break; - } - - op = acpi_ps_get_depth_next (start_op, op); - } - - acpi_os_printf ("Method contains: %X AML Opcodes - %X Operators, %X Operands\n", - num_ops, num_operators, num_operands); - - acpi_os_printf ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n", - num_remaining_ops, num_remaining_operators, num_remaining_operands); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_locals - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display all locals for the currently running control method - * - ******************************************************************************/ - -void -acpi_db_display_locals (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - acpi_os_printf ("Local Variables for method [%4.4s]:\n", node->name.ascii); - - for (i = 0; i < MTH_NUM_LOCALS; i++) { - obj_desc = walk_state->local_variables[i].object; - acpi_os_printf ("Local%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_arguments - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display all arguments for the currently running control method - * - ******************************************************************************/ - -void -acpi_db_display_arguments (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - u32 num_args; - u32 concurrency; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - num_args = obj_desc->method.param_count; - concurrency = obj_desc->method.concurrency; - - acpi_os_printf ("Method [%4.4s] has %X arguments, max concurrency = %X\n", - node->name.ascii, num_args, concurrency); - - for (i = 0; i < num_args; i++) { - obj_desc = walk_state->arguments[i].object; - acpi_os_printf ("Arg%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_results - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display current contents of a method result stack - * - ******************************************************************************/ - -void -acpi_db_display_results (void) -{ - u32 i; - acpi_walk_state *walk_state; - acpi_operand_object *obj_desc; - u32 num_results = 0; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - obj_desc = walk_state->method_desc; - node = walk_state->method_node; - - if (walk_state->results) { - num_results = walk_state->results->results.num_results; - } - - acpi_os_printf ("Method [%4.4s] has %X stacked result objects\n", - node->name.ascii, num_results); - - for (i = 0; i < num_results; i++) { - obj_desc = walk_state->results->results.obj_desc[i]; - acpi_os_printf ("Result%d: ", i); - acpi_db_display_internal_object (obj_desc, walk_state); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_calling_tree - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display current calling tree of nested control methods - * - ******************************************************************************/ - -void -acpi_db_display_calling_tree (void) -{ - acpi_walk_state *walk_state; - acpi_namespace_node *node; - - - walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list); - if (!walk_state) { - acpi_os_printf ("There is no method currently executing\n"); - return; - } - - node = walk_state->method_node; - acpi_os_printf ("Current Control Method Call Tree\n"); - - while (walk_state) { - node = walk_state->method_node; - - acpi_os_printf (" [%4.4s]\n", node->name.ascii); - - walk_state = walk_state->next; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_result_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Display the result of an AML opcode - * - * Note: Curently only displays the result object if we are single stepping. - * However, this output may be useful in other contexts and could be enabled - * to do so if needed. - * - ******************************************************************************/ - -void -acpi_db_display_result_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - - /* Only display if single stepping */ - - if (!acpi_gbl_cm_single_step) { - return; - } - - acpi_os_printf ("Result_obj: "); - acpi_db_display_internal_object (obj_desc, walk_state); - acpi_os_printf ("\n"); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_argument_object - * - * PARAMETERS: Obj_desc - Object to be displayed - * Walk_state - Current walk state - * - * RETURN: None - * - * DESCRIPTION: Display the result of an AML opcode - * - ******************************************************************************/ - -void -acpi_db_display_argument_object ( - acpi_operand_object *obj_desc, - acpi_walk_state *walk_state) -{ - - if (!acpi_gbl_cm_single_step) { - return; - } - - acpi_os_printf ("Arg_obj: "); - acpi_db_display_internal_object (obj_desc, walk_state); -} - -#endif /* ENABLE_DEBUGGER */ - diff -Nru a/drivers/acpi/debugger/dbexec.c b/drivers/acpi/debugger/dbexec.c --- a/drivers/acpi/debugger/dbexec.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,398 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbexec - debugger control method execution - * $Revision: 41 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acdebug.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbexec") - - -static acpi_db_method_info acpi_gbl_db_method_info; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_method - * - * PARAMETERS: Info - Valid info segment - * Return_obj - Where to put return object - * - * RETURN: Status - * - * DESCRIPTION: Execute a control method. - * - ******************************************************************************/ - -acpi_status -acpi_db_execute_method ( - acpi_db_method_info *info, - acpi_buffer *return_obj) -{ - acpi_status status; - acpi_object_list param_objects; - acpi_object params[MTH_NUM_ARGS]; - u32 i; - - - if (acpi_gbl_db_output_to_file && !acpi_dbg_level) { - acpi_os_printf ("Warning: debug output is not enabled!\n"); - } - - /* Are there arguments to the method? */ - - if (info->args && info->args[0]) { - for (i = 0; info->args[i] && i < MTH_NUM_ARGS; i++) { - params[i].type = ACPI_TYPE_INTEGER; - params[i].integer.value = ACPI_STRTOUL (info->args[i], NULL, 16); - } - - param_objects.pointer = params; - param_objects.count = i; - } - else { - /* Setup default parameters */ - - params[0].type = ACPI_TYPE_INTEGER; - params[0].integer.value = 0x01020304; - - params[1].type = ACPI_TYPE_STRING; - params[1].string.length = 12; - params[1].string.pointer = "AML Debugger"; - - param_objects.pointer = params; - param_objects.count = 2; - } - - /* Prepare for a return object of arbitrary size */ - - return_obj->pointer = acpi_gbl_db_buffer; - return_obj->length = ACPI_DEBUG_BUFFER_SIZE; - - /* Do the actual method execution */ - - status = acpi_evaluate_object (NULL, info->pathname, ¶m_objects, return_obj); - - acpi_gbl_cm_single_step = FALSE; - acpi_gbl_method_executing = FALSE; - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_setup - * - * PARAMETERS: Info - Valid method info - * - * RETURN: Status - * - * DESCRIPTION: Setup info segment prior to method execution - * - ******************************************************************************/ - -void -acpi_db_execute_setup ( - acpi_db_method_info *info) -{ - - /* Catenate the current scope to the supplied name */ - - info->pathname[0] = 0; - if ((info->name[0] != '\\') && - (info->name[0] != '/')) { - ACPI_STRCAT (info->pathname, acpi_gbl_db_scope_buf); - } - - ACPI_STRCAT (info->pathname, info->name); - acpi_db_prep_namestring (info->pathname); - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - acpi_os_printf ("Executing %s\n", info->pathname); - - if (info->flags & EX_SINGLE_STEP) { - acpi_gbl_cm_single_step = TRUE; - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - } - - else { - /* No single step, allow redirection to a file */ - - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_outstanding_allocations - * - * PARAMETERS: None - * - * RETURN: Current global allocation count minus cache entries - * - * DESCRIPTION: Determine the current number of "outstanding" allocations -- - * those allocations that have not been freed and also are not - * in one of the various object caches. - * - ******************************************************************************/ - -u32 -acpi_db_get_outstanding_allocations ( - void) -{ - u32 outstanding = 0; - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - u32 i; - - - for (i = ACPI_MEM_LIST_FIRST_CACHE_LIST; i < ACPI_NUM_MEM_LISTS; i++) { - outstanding += (acpi_gbl_memory_lists[i].total_allocated - - acpi_gbl_memory_lists[i].total_freed - - acpi_gbl_memory_lists[i].cache_depth); - } -#endif - - return (outstanding); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute - * - * PARAMETERS: Name - Name of method to execute - * Args - Parameters to the method - * Flags - single step/no single step - * - * RETURN: Status - * - * DESCRIPTION: Execute a control method. Name is relative to the current - * scope. - * - ******************************************************************************/ - -void -acpi_db_execute ( - NATIVE_CHAR *name, - NATIVE_CHAR **args, - u32 flags) -{ - acpi_status status; - acpi_buffer return_obj; - - -#ifdef ACPI_DEBUG - u32 previous_allocations; - u32 allocations; - - - /* Memory allocation tracking */ - - previous_allocations = acpi_db_get_outstanding_allocations (); -#endif - - acpi_gbl_db_method_info.name = name; - acpi_gbl_db_method_info.args = args; - acpi_gbl_db_method_info.flags = flags; - - acpi_db_execute_setup (&acpi_gbl_db_method_info); - status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj); - - /* - * Allow any handlers in separate threads to complete. - * (Such as Notify handlers invoked from AML executed above). - */ - acpi_os_sleep (0, 10); - - -#ifdef ACPI_DEBUG - - /* Memory allocation tracking */ - - allocations = acpi_db_get_outstanding_allocations () - previous_allocations; - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - - if (allocations > 0) { - acpi_os_printf ("Outstanding: %ld allocations after execution\n", - allocations); - } -#endif - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Execution of %s failed with status %s\n", - acpi_gbl_db_method_info.pathname, acpi_format_exception (status)); - } - - else { - /* Display a return object, if any */ - - if (return_obj.length) { - acpi_os_printf ("Execution of %s returned object %p Buflen %X\n", - acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length); - acpi_db_dump_object (return_obj.pointer, 1); - } - } - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_method_thread - * - * PARAMETERS: Context - Execution info segment - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void ACPI_SYSTEM_XFACE -acpi_db_method_thread ( - void *context) -{ - acpi_status status; - acpi_db_method_info *info = context; - u32 i; - acpi_buffer return_obj; - - - for (i = 0; i < info->num_loops; i++) { - status = acpi_db_execute_method (info, &return_obj); - if (ACPI_SUCCESS (status)) { - if (return_obj.length) { - acpi_os_printf ("Execution of %s returned object %p Buflen %X\n", - info->pathname, return_obj.pointer, return_obj.length); - acpi_db_dump_object (return_obj.pointer, 1); - } - } - } - - /* Signal our completion */ - - status = acpi_os_signal_semaphore (info->thread_gate, 1); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not signal debugger semaphore\n"); - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_create_execution_threads - * - * PARAMETERS: Num_threads_arg - Number of threads to create - * Num_loops_arg - Loop count for the thread(s) - * Method_name_arg - Control method to execute - * - * RETURN: None - * - * DESCRIPTION: Create threads to execute method(s) - * - ******************************************************************************/ - -void -acpi_db_create_execution_threads ( - NATIVE_CHAR *num_threads_arg, - NATIVE_CHAR *num_loops_arg, - NATIVE_CHAR *method_name_arg) -{ - acpi_status status; - u32 num_threads; - u32 num_loops; - u32 i; - acpi_handle thread_gate; - - - /* Get the arguments */ - - num_threads = ACPI_STRTOUL (num_threads_arg, NULL, 0); - num_loops = ACPI_STRTOUL (num_loops_arg, NULL, 0); - - if (!num_threads || !num_loops) { - acpi_os_printf ("Bad argument: Threads %X, Loops %X\n", num_threads, num_loops); - return; - } - - /* Create the synchronization semaphore */ - - status = acpi_os_create_semaphore (1, 0, &thread_gate); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not create semaphore, %s\n", acpi_format_exception (status)); - return; - } - - /* Setup the context to be passed to each thread */ - - acpi_gbl_db_method_info.name = method_name_arg; - acpi_gbl_db_method_info.args = NULL; - acpi_gbl_db_method_info.flags = 0; - acpi_gbl_db_method_info.num_loops = num_loops; - acpi_gbl_db_method_info.thread_gate = thread_gate; - - acpi_db_execute_setup (&acpi_gbl_db_method_info); - - /* Create the threads */ - - acpi_os_printf ("Creating %X threads to execute %X times each\n", num_threads, num_loops); - - for (i = 0; i < (num_threads); i++) { - status = acpi_os_queue_for_execution (OSD_PRIORITY_MED, acpi_db_method_thread, &acpi_gbl_db_method_info); - if (ACPI_FAILURE (status)) { - break; - } - } - - /* Wait for all threads to complete */ - - i = num_threads; - while (i) /* Brain damage for OSD implementations that only support wait of 1 unit */ { - status = acpi_os_wait_semaphore (thread_gate, 1, WAIT_FOREVER); - i--; - } - - /* Cleanup and exit */ - - (void) acpi_os_delete_semaphore (thread_gate); - - acpi_db_set_output_destination (ACPI_DB_DUPLICATE_OUTPUT); - acpi_os_printf ("All threads (%X) have completed\n", num_threads); - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); -} - - -#endif /* ENABLE_DEBUGGER */ - - diff -Nru a/drivers/acpi/debugger/dbfileio.c b/drivers/acpi/debugger/dbfileio.c --- a/drivers/acpi/debugger/dbfileio.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,393 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbfileio - Debugger file I/O commands. These can't usually - * be used when running the debugger in Ring 0 (Kernel mode) - * $Revision: 63 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acdebug.h" -#include "acnamesp.h" -#include "actables.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbfileio") - - -/* - * NOTE: this is here for lack of a better place. It is used in all - * flavors of the debugger, need LCD file - */ -#ifdef ACPI_APPLICATION -#include -FILE *acpi_gbl_debug_file = NULL; -#endif - - -acpi_table_header *acpi_gbl_db_table_ptr = NULL; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_match_argument - * - * PARAMETERS: User_argument - User command line - * Arguments - Array of commands to match against - * - * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found - * - * DESCRIPTION: Search command array for a command match - * - ******************************************************************************/ - -acpi_object_type -acpi_db_match_argument ( - NATIVE_CHAR *user_argument, - ARGUMENT_INFO *arguments) -{ - u32 i; - - - if (!user_argument || user_argument[0] == 0) { - return (ACPI_TYPE_NOT_FOUND); - } - - for (i = 0; arguments[i].name; i++) { - if (ACPI_STRSTR (arguments[i].name, user_argument) == arguments[i].name) { - return (i); - } - } - - /* Argument not recognized */ - - return (ACPI_TYPE_NOT_FOUND); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_close_debug_file - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: If open, close the current debug output file - * - ******************************************************************************/ - -void -acpi_db_close_debug_file ( - void) -{ - -#ifdef ACPI_APPLICATION - - if (acpi_gbl_debug_file) { - fclose (acpi_gbl_debug_file); - acpi_gbl_debug_file = NULL; - acpi_gbl_db_output_to_file = FALSE; - acpi_os_printf ("Debug output file %s closed\n", acpi_gbl_db_debug_filename); - } -#endif - -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_open_debug_file - * - * PARAMETERS: Name - Filename to open - * - * RETURN: Status - * - * DESCRIPTION: Open a file where debug output will be directed. - * - ******************************************************************************/ - -void -acpi_db_open_debug_file ( - NATIVE_CHAR *name) -{ - -#ifdef ACPI_APPLICATION - - acpi_db_close_debug_file (); - acpi_gbl_debug_file = fopen (name, "w+"); - if (acpi_gbl_debug_file) { - acpi_os_printf ("Debug output file %s opened\n", name); - ACPI_STRCPY (acpi_gbl_db_debug_filename, name); - acpi_gbl_db_output_to_file = TRUE; - } - else { - acpi_os_printf ("Could not open debug file %s\n", name); - } - -#endif -} - - -#ifdef ACPI_APPLICATION -/******************************************************************************* - * - * FUNCTION: Acpi_db_load_table - * - * PARAMETERS: fp - File that contains table - * Table_ptr - Return value, buffer with table - * Table_lenght - Return value, length of table - * - * RETURN: Status - * - * DESCRIPTION: Load the DSDT from the file pointer - * - ******************************************************************************/ - -static acpi_status -acpi_db_load_table( - FILE *fp, - acpi_table_header **table_ptr, - u32 *table_length) -{ - acpi_table_header table_header; - u8 *aml_start; - u32 aml_length; - u32 actual; - acpi_status status; - - - /* Read the table header */ - - if (fread (&table_header, 1, sizeof (table_header), fp) != sizeof (acpi_table_header)) { - acpi_os_printf ("Couldn't read the table header\n"); - return (AE_BAD_SIGNATURE); - } - - - /* Validate the table header/length */ - - status = acpi_tb_validate_table_header (&table_header); - if ((ACPI_FAILURE (status)) || - (table_header.length > 524288)) /* 1/2 Mbyte should be enough */ { - acpi_os_printf ("Table header is invalid!\n"); - return (AE_ERROR); - } - - - /* We only support a limited number of table types */ - - if (ACPI_STRNCMP ((char *) table_header.signature, DSDT_SIG, 4) && - ACPI_STRNCMP ((char *) table_header.signature, PSDT_SIG, 4) && - ACPI_STRNCMP ((char *) table_header.signature, SSDT_SIG, 4)) { - acpi_os_printf ("Table signature is invalid\n"); - ACPI_DUMP_BUFFER (&table_header, sizeof (acpi_table_header)); - return (AE_ERROR); - } - - /* Allocate a buffer for the table */ - - *table_length = table_header.length; - *table_ptr = acpi_os_allocate ((size_t) *table_length); - if (!*table_ptr) { - acpi_os_printf ("Could not allocate memory for ACPI table %4.4s (size=%X)\n", - table_header.signature, table_header.length); - return (AE_NO_MEMORY); - } - - - aml_start = (u8 *) *table_ptr + sizeof (table_header); - aml_length = *table_length - sizeof (table_header); - - /* Copy the header to the buffer */ - - ACPI_MEMCPY (*table_ptr, &table_header, sizeof (table_header)); - - /* Get the rest of the table */ - - actual = fread (aml_start, 1, (size_t) aml_length, fp); - if (actual == aml_length) { - return (AE_OK); - } - - if (actual > 0) { - acpi_os_printf ("Warning - reading table, asked for %X got %X\n", aml_length, actual); - return (AE_OK); - } - - - acpi_os_printf ("Error - could not read the table file\n"); - acpi_os_free (*table_ptr); - *table_ptr = NULL; - *table_length = 0; - - return (AE_ERROR); -} -#endif - - -/******************************************************************************* - * - * FUNCTION: Ae_local_load_table - * - * PARAMETERS: Table_ptr - pointer to a buffer containing the entire - * table to be loaded - * - * RETURN: Status - * - * DESCRIPTION: This function is called to load a table from the caller's - * buffer. The buffer must contain an entire ACPI Table including - * a valid header. The header fields will be verified, and if it - * is determined that the table is invalid, the call will fail. - * - * If the call fails an appropriate status will be returned. - * - ******************************************************************************/ - -acpi_status -ae_local_load_table ( - acpi_table_header *table_ptr) -{ - acpi_status status; - acpi_table_desc table_info; - - - ACPI_FUNCTION_TRACE ("Ae_local_load_table"); - - if (!table_ptr) { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* Install the new table into the local data structures */ - - table_info.pointer = table_ptr; - - status = acpi_tb_install_table (&table_info); - if (ACPI_FAILURE (status)) { - /* Free table allocated by Acpi_tb_get_table */ - - acpi_tb_delete_single_table (&table_info); - return_ACPI_STATUS (status); - } - - -#ifndef PARSER_ONLY - status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); - if (ACPI_FAILURE (status)) { - /* Uninstall table and free the buffer */ - - acpi_tb_delete_acpi_table (ACPI_TABLE_DSDT); - return_ACPI_STATUS (status); - } -#endif - - return_ACPI_STATUS (status); -} - - -#ifdef ACPI_APPLICATION -acpi_status -acpi_db_get_acpi_table ( - NATIVE_CHAR *filename) -{ - FILE *fp; - u32 table_length; - acpi_status status; - - /* Open the file */ - - fp = fopen (filename, "rb"); - if (!fp) { - acpi_os_printf ("Could not open file %s\n", filename); - return (AE_ERROR); - } - - - /* Get the entire file */ - - acpi_os_printf ("Loading Acpi table from file %s\n", filename); - status = acpi_db_load_table (fp, &acpi_gbl_db_table_ptr, &table_length); - fclose(fp); - - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Couldn't get table from the file\n"); - return (status); - } - - return (AE_OK); - } -#endif - -/******************************************************************************* - * - * FUNCTION: Acpi_db_load_acpi_table - * - * PARAMETERS: Filname - File where table is located - * - * RETURN: Status - * - * DESCRIPTION: Load an ACPI table from a file - * - ******************************************************************************/ - -acpi_status -acpi_db_load_acpi_table ( - NATIVE_CHAR *filename) { -#ifdef ACPI_APPLICATION - acpi_status status; - - - status = acpi_db_get_acpi_table (filename); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Attempt to recognize and install the table */ - - status = ae_local_load_table (acpi_gbl_db_table_ptr); - if (ACPI_FAILURE (status)) { - if (status == AE_ALREADY_EXISTS) { - acpi_os_printf ("Table %4.4s is already installed\n", - acpi_gbl_db_table_ptr->signature); - } - else { - acpi_os_printf ("Could not install table, %s\n", - acpi_format_exception (status)); - } - - return (status); - } - - acpi_os_printf ("%4.4s at %p successfully installed and loaded\n", - acpi_gbl_db_table_ptr->signature, acpi_gbl_db_table_ptr); - - acpi_gbl_acpi_hardware_present = FALSE; - -#endif /* ACPI_APPLICATION */ - return (AE_OK); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -Nru a/drivers/acpi/debugger/dbhistry.c b/drivers/acpi/debugger/dbhistry.c --- a/drivers/acpi/debugger/dbhistry.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,189 +0,0 @@ -/****************************************************************************** - * - * Module Name: dbhistry - debugger HISTORY command - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acdebug.h" - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbhistry") - - -#define HI_NO_HISTORY 0 -#define HI_RECORD_HISTORY 1 -#define HISTORY_SIZE 20 - - -typedef struct history_info -{ - NATIVE_CHAR command[80]; - u32 cmd_num; - -} HISTORY_INFO; - - -static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE]; -static u16 acpi_gbl_lo_history = 0; -static u16 acpi_gbl_num_history = 0; -static u16 acpi_gbl_next_history_index = 0; -static u32 acpi_gbl_next_cmd_num = 1; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_add_to_history - * - * PARAMETERS: Command_line - Command to add - * - * RETURN: None - * - * DESCRIPTION: Add a command line to the history buffer. - * - ******************************************************************************/ - -void -acpi_db_add_to_history ( - NATIVE_CHAR *command_line) -{ - - /* Put command into the next available slot */ - - ACPI_STRCPY (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command, command_line); - - acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num = acpi_gbl_next_cmd_num; - - /* Adjust indexes */ - - if ((acpi_gbl_num_history == HISTORY_SIZE) && - (acpi_gbl_next_history_index == acpi_gbl_lo_history)) { - acpi_gbl_lo_history++; - if (acpi_gbl_lo_history >= HISTORY_SIZE) { - acpi_gbl_lo_history = 0; - } - } - - acpi_gbl_next_history_index++; - if (acpi_gbl_next_history_index >= HISTORY_SIZE) { - acpi_gbl_next_history_index = 0; - } - - acpi_gbl_next_cmd_num++; - if (acpi_gbl_num_history < HISTORY_SIZE) { - acpi_gbl_num_history++; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_history - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Display the contents of the history buffer - * - ******************************************************************************/ - -void -acpi_db_display_history (void) -{ - NATIVE_UINT i; - u16 history_index; - - - history_index = acpi_gbl_lo_history; - - /* Dump entire history buffer */ - - for (i = 0; i < acpi_gbl_num_history; i++) { - acpi_os_printf ("%ld %s\n", acpi_gbl_history_buffer[history_index].cmd_num, - acpi_gbl_history_buffer[history_index].command); - - history_index++; - if (history_index >= HISTORY_SIZE) { - history_index = 0; - } - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_from_history - * - * PARAMETERS: Command_num_arg - String containing the number of the - * command to be retrieved - * - * RETURN: None - * - * DESCRIPTION: Get a command from the history buffer - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_db_get_from_history ( - NATIVE_CHAR *command_num_arg) -{ - NATIVE_UINT i; - u16 history_index; - u32 cmd_num; - - - if (command_num_arg == NULL) { - cmd_num = acpi_gbl_next_cmd_num - 1; - } - - else { - cmd_num = ACPI_STRTOUL (command_num_arg, NULL, 0); - } - - /* Search history buffer */ - - history_index = acpi_gbl_lo_history; - for (i = 0; i < acpi_gbl_num_history; i++) { - if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) { - /* Found the commnad, return it */ - - return (acpi_gbl_history_buffer[history_index].command); - } - - - history_index++; - if (history_index >= HISTORY_SIZE) { - history_index = 0; - } - } - - acpi_os_printf ("Invalid history number: %d\n", history_index); - return (NULL); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -Nru a/drivers/acpi/debugger/dbinput.c b/drivers/acpi/debugger/dbinput.c --- a/drivers/acpi/debugger/dbinput.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,892 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbinput - user front-end to the AML debugger - * $Revision: 86 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbinput") - - -/* - * Top-level debugger commands. - * - * This list of commands must match the string table below it - */ -enum acpi_ex_debugger_commands -{ - CMD_NOT_FOUND = 0, - CMD_NULL, - CMD_ALLOCATIONS, - CMD_ARGS, - CMD_ARGUMENTS, - CMD_BREAKPOINT, - CMD_CALL, - CMD_CLOSE, - CMD_DEBUG, - CMD_DUMP, - CMD_ENABLEACPI, - CMD_EVENT, - CMD_EXECUTE, - CMD_EXIT, - CMD_FIND, - CMD_GO, - CMD_HELP, - CMD_HELP2, - CMD_HISTORY, - CMD_HISTORY_EXE, - CMD_HISTORY_LAST, - CMD_INFORMATION, - CMD_INTEGRITY, - CMD_INTO, - CMD_LEVEL, - CMD_LIST, - CMD_LOAD, - CMD_LOCALS, - CMD_LOCKS, - CMD_METHODS, - CMD_NAMESPACE, - CMD_NOTIFY, - CMD_OBJECT, - CMD_OPEN, - CMD_OWNER, - CMD_PREFIX, - CMD_QUIT, - CMD_REFERENCES, - CMD_RESOURCES, - CMD_RESULTS, - CMD_SET, - CMD_STATS, - CMD_STOP, - CMD_TABLES, - CMD_TERMINATE, - CMD_THREADS, - CMD_TREE, - CMD_UNLOAD -}; - -#define CMD_FIRST_VALID 2 - - -static const COMMAND_INFO acpi_gbl_db_commands[] = -{ {"", 0}, - {"", 0}, - {"ALLOCATIONS", 0}, - {"ARGS", 0}, - {"ARGUMENTS", 0}, - {"BREAKPOINT", 1}, - {"CALL", 0}, - {"CLOSE", 0}, - {"DEBUG", 1}, - {"DUMP", 1}, - {"ENABLEACPI", 0}, - {"EVENT", 1}, - {"EXECUTE", 1}, - {"EXIT", 0}, - {"FIND", 1}, - {"GO", 0}, - {"HELP", 0}, - {"?", 0}, - {"HISTORY", 0}, - {"!", 1}, - {"!!", 0}, - {"INFORMATION", 0}, - {"INTEGRITY", 0}, - {"INTO", 0}, - {"LEVEL", 0}, - {"LIST", 0}, - {"LOAD", 1}, - {"LOCALS", 0}, - {"LOCKS", 0}, - {"METHODS", 0}, - {"NAMESPACE", 0}, - {"NOTIFY", 2}, - {"OBJECT", 1}, - {"OPEN", 1}, - {"OWNER", 1}, - {"PREFIX", 0}, - {"QUIT", 0}, - {"REFERENCES", 1}, - {"RESOURCES", 1}, - {"RESULTS", 0}, - {"SET", 3}, - {"STATS", 0}, - {"STOP", 0}, - {"TABLES", 0}, - {"TERMINATE", 0}, - {"THREADS", 3}, - {"TREE", 0}, - {"UNLOAD", 1}, - {NULL, 0} -}; - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_help - * - * PARAMETERS: Help_type - Subcommand (optional) - * - * RETURN: None - * - * DESCRIPTION: Print a usage message. - * - ******************************************************************************/ - -void -acpi_db_display_help ( - NATIVE_CHAR *help_type) -{ - - - /* No parameter, just give the overview */ - - if (!help_type) - { - acpi_os_printf ("ACPI CA Debugger Commands\n\n"); - acpi_os_printf ("The following classes of commands are available. Help is available for\n"); - acpi_os_printf ("each class by entering \"Help \"\n\n"); - acpi_os_printf (" [GENERAL] General-Purpose Commands\n"); - acpi_os_printf (" [NAMESPACE] Namespace Access Commands\n"); - acpi_os_printf (" [METHOD] Control Method Execution Commands\n"); - acpi_os_printf (" [FILE] File I/O Commands\n"); - return; - - } - - /* - * Parameter is the command class - * - * The idea here is to keep each class of commands smaller than a screenful - */ - switch (help_type[0]) - { - case 'G': - acpi_os_printf ("\n_general-Purpose Commands\n\n"); - acpi_os_printf ("Allocations Display list of current memory allocations\n"); - acpi_os_printf ("Dump
|\n"); - acpi_os_printf (" [Byte|Word|Dword|Qword] Display ACPI objects or memory\n"); - acpi_os_printf ("Enable_acpi Enable ACPI (hardware) mode\n"); - acpi_os_printf ("Help This help screen\n"); - acpi_os_printf ("History Display command history buffer\n"); - acpi_os_printf ("Level [] [console] Get/Set debug level for file or console\n"); - acpi_os_printf ("Locks Current status of internal mutexes\n"); - acpi_os_printf ("Quit or Exit Exit this command\n"); - acpi_os_printf ("Stats [Allocations|Memory|Misc\n"); - acpi_os_printf (" |Objects|Tables] Display namespace and memory statistics\n"); - acpi_os_printf ("Tables Display info about loaded ACPI tables\n"); - acpi_os_printf ("Unload [Instance] Unload an ACPI table\n"); - acpi_os_printf ("! Execute command from history buffer\n"); - acpi_os_printf ("!! Execute last command again\n"); - return; - - case 'N': - acpi_os_printf ("\n_namespace Access Commands\n\n"); - acpi_os_printf ("Debug [Arguments] Single Step a control method\n"); - acpi_os_printf ("Event Generate Acpi_event (Fixed/GPE)\n"); - acpi_os_printf ("Execute [Arguments] Execute control method\n"); - acpi_os_printf ("Find (? is wildcard) Find ACPI name(s) with wildcards\n"); - acpi_os_printf ("Method Display list of loaded control methods\n"); - acpi_os_printf ("Namespace [|] [Depth] Display loaded namespace tree/subtree\n"); - acpi_os_printf ("Notify Send a notification\n"); - acpi_os_printf ("Objects Display all objects of the given type\n"); - acpi_os_printf ("Owner [Depth] Display loaded namespace by object owner\n"); - acpi_os_printf ("Prefix [] Set or Get current execution prefix\n"); - acpi_os_printf ("References Find all references to object at addr\n"); - acpi_os_printf ("Resources xxx Get and display resources\n"); - acpi_os_printf ("Terminate Delete namespace and all internal objects\n"); - acpi_os_printf ("Thread Spawn threads to execute method(s)\n"); - return; - - case 'M': - acpi_os_printf ("\n_control Method Execution Commands\n\n"); - acpi_os_printf ("Arguments (or Args) Display method arguments\n"); - acpi_os_printf ("Breakpoint Set an AML execution breakpoint\n"); - acpi_os_printf ("Call Run to next control method invocation\n"); - acpi_os_printf ("Go Allow method to run to completion\n"); - acpi_os_printf ("Information Display info about the current method\n"); - acpi_os_printf ("Into Step into (not over) a method call\n"); - acpi_os_printf ("List [# of Aml Opcodes] Display method ASL statements\n"); - acpi_os_printf ("Locals Display method local variables\n"); - acpi_os_printf ("Results Display method result stack\n"); - acpi_os_printf ("Set <#> Set method data (Arguments/Locals)\n"); - acpi_os_printf ("Stop Terminate control method\n"); - acpi_os_printf ("Tree Display control method calling tree\n"); - acpi_os_printf (" Single step next AML opcode (over calls)\n"); - return; - - case 'F': - acpi_os_printf ("\n_file I/O Commands\n\n"); - acpi_os_printf ("Close Close debug output file\n"); - acpi_os_printf ("Open Open a file for debug output\n"); - acpi_os_printf ("Load Load ACPI table from a file\n"); - return; - - default: - acpi_os_printf ("Unrecognized Command Class: %X\n", help_type); - return; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_next_token - * - * PARAMETERS: String - Command buffer - * Next - Return value, end of next token - * - * RETURN: Pointer to the start of the next token. - * - * DESCRIPTION: Command line parsing. Get the next token on the command line - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_db_get_next_token ( - NATIVE_CHAR *string, - NATIVE_CHAR **next) -{ - NATIVE_CHAR *start; - - - /* At end of buffer? */ - - if (!string || !(*string)) - { - return (NULL); - } - - /* Get rid of any spaces at the beginning */ - - if (*string == ' ') - { - while (*string && (*string == ' ')) - { - string++; - } - - if (!(*string)) - { - return (NULL); - } - } - - start = string; - - /* Find end of token */ - - while (*string && (*string != ' ')) - { - string++; - } - - if (!(*string)) - { - *next = NULL; - } - else - { - *string = 0; - *next = string + 1; - } - - return (start); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_get_line - * - * PARAMETERS: Input_buffer - Command line buffer - * - * RETURN: None - * - * DESCRIPTION: Get the next command line from the user. Gets entire line - * up to the next newline - * - ******************************************************************************/ - -u32 -acpi_db_get_line ( - NATIVE_CHAR *input_buffer) -{ - u32 i; - u32 count; - NATIVE_CHAR *next; - NATIVE_CHAR *this; - - - ACPI_STRCPY (acpi_gbl_db_parsed_buf, input_buffer); - ACPI_STRUPR (acpi_gbl_db_parsed_buf); - - this = acpi_gbl_db_parsed_buf; - for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) - { - acpi_gbl_db_args[i] = acpi_db_get_next_token (this, &next); - if (!acpi_gbl_db_args[i]) - { - break; - } - - this = next; - } - - /* Uppercase the actual command */ - - if (acpi_gbl_db_args[0]) - { - ACPI_STRUPR (acpi_gbl_db_args[0]); - } - - count = i; - if (count) - { - count--; /* Number of args only */ - } - - return (count); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_match_command - * - * PARAMETERS: User_command - User command line - * - * RETURN: Index into command array, -1 if not found - * - * DESCRIPTION: Search command array for a command match - * - ******************************************************************************/ - -u32 -acpi_db_match_command ( - NATIVE_CHAR *user_command) -{ - u32 i; - - - if (!user_command || user_command[0] == 0) - { - return (CMD_NULL); - } - - for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) - { - if (ACPI_STRSTR (acpi_gbl_db_commands[i].name, user_command) == - acpi_gbl_db_commands[i].name) - { - return (i); - } - } - - /* Command not recognized */ - - return (CMD_NOT_FOUND); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_command_dispatch - * - * PARAMETERS: Input_buffer - Command line buffer - * Walk_state - Current walk - * Op - Current (executing) parse op - * - * RETURN: Status - * - * DESCRIPTION: Command dispatcher. Called from two places: - * - ******************************************************************************/ - -acpi_status -acpi_db_command_dispatch ( - NATIVE_CHAR *input_buffer, - acpi_walk_state *walk_state, - acpi_parse_object *op) -{ - u32 temp; - u32 command_index; - u32 param_count; - NATIVE_CHAR *command_line; - acpi_status status = AE_CTRL_TRUE; - - - /* If Acpi_terminate has been called, terminate this thread */ - - if (acpi_gbl_db_terminate_threads) - { - return (AE_CTRL_TERMINATE); - } - - param_count = acpi_db_get_line (input_buffer); - command_index = acpi_db_match_command (acpi_gbl_db_args[0]); - temp = 0; - - /* Verify that we have the minimum number of params */ - - if (param_count < acpi_gbl_db_commands[command_index].min_args) - { - acpi_os_printf ("%d parameters entered, [%s] requires %d parameters\n", - param_count, acpi_gbl_db_commands[command_index].name, acpi_gbl_db_commands[command_index].min_args); - return (AE_CTRL_TRUE); - } - - /* Decode and dispatch the command */ - - switch (command_index) - { - case CMD_NULL: - if (op) - { - return (AE_OK); - } - break; - - case CMD_ALLOCATIONS: - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_ut_dump_allocations ((u32) -1, NULL); -#endif - break; - - case CMD_ARGS: - case CMD_ARGUMENTS: - acpi_db_display_arguments (); - break; - - case CMD_BREAKPOINT: - acpi_db_set_method_breakpoint (acpi_gbl_db_args[1], walk_state, op); - break; - - case CMD_CALL: - acpi_db_set_method_call_breakpoint (op); - status = AE_OK; - break; - - case CMD_CLOSE: - acpi_db_close_debug_file (); - break; - - case CMD_DEBUG: - acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_SINGLE_STEP); - break; - - case CMD_DUMP: - acpi_db_decode_and_display_object (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_ENABLEACPI: - status = acpi_enable(); - if (ACPI_FAILURE(status)) - { - acpi_os_printf("Acpi_enable failed (Status=%X)\n", status); - return (status); - } - break; - - case CMD_EVENT: - acpi_os_printf ("Event command not implemented\n"); - break; - - case CMD_EXECUTE: - acpi_db_execute (acpi_gbl_db_args[1], &acpi_gbl_db_args[2], EX_NO_SINGLE_STEP); - break; - - case CMD_FIND: - status = acpi_db_find_name_in_namespace (acpi_gbl_db_args[1]); - break; - - case CMD_GO: - acpi_gbl_cm_single_step = FALSE; - return (AE_OK); - - case CMD_HELP: - case CMD_HELP2: - acpi_db_display_help (acpi_gbl_db_args[1]); - break; - - case CMD_HISTORY: - acpi_db_display_history (); - break; - - case CMD_HISTORY_EXE: - command_line = acpi_db_get_from_history (acpi_gbl_db_args[1]); - if (!command_line) - { - return (AE_CTRL_TRUE); - } - - status = acpi_db_command_dispatch (command_line, walk_state, op); - if (ACPI_SUCCESS (status)) - { - status = AE_CTRL_TRUE; - } - return (status); - - case CMD_HISTORY_LAST: - command_line = acpi_db_get_from_history (NULL); - if (!command_line) - { - return (AE_CTRL_TRUE); - } - - status = acpi_db_command_dispatch (command_line, walk_state, op); - if (ACPI_SUCCESS (status)) - { - status = AE_CTRL_TRUE; - } - return (status); - - case CMD_INFORMATION: - acpi_db_display_method_info (op); - break; - - case CMD_INTEGRITY: - acpi_db_check_integrity (); - break; - - case CMD_INTO: - if (op) - { - acpi_gbl_cm_single_step = TRUE; - return (AE_OK); - } - break; - - case CMD_LEVEL: - if (param_count == 0) - { - acpi_os_printf ("Current debug level for file output is: %8.8lX\n", acpi_gbl_db_debug_level); - acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level); - } - else if (param_count == 2) - { - temp = acpi_gbl_db_console_debug_level; - acpi_gbl_db_console_debug_level = ACPI_STRTOUL (acpi_gbl_db_args[1], NULL, 16); - acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level); - } - else - { - temp = acpi_gbl_db_debug_level; - acpi_gbl_db_debug_level = ACPI_STRTOUL (acpi_gbl_db_args[1], NULL, 16); - acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level); - } - break; - - case CMD_LIST: - acpi_db_disassemble_aml (acpi_gbl_db_args[1], op); - break; - - case CMD_LOAD: - status = acpi_db_load_acpi_table (acpi_gbl_db_args[1]); - if (ACPI_FAILURE (status)) - { - return (status); - } - break; - - case CMD_LOCKS: - acpi_db_display_locks (); - break; - - case CMD_LOCALS: - acpi_db_display_locals (); - break; - - case CMD_METHODS: - status = acpi_db_display_objects ("METHOD", acpi_gbl_db_args[1]); - break; - - case CMD_NAMESPACE: - acpi_db_dump_namespace (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_NOTIFY: - temp = ACPI_STRTOUL (acpi_gbl_db_args[2], NULL, 0); - acpi_db_send_notify (acpi_gbl_db_args[1], temp); - break; - - case CMD_OBJECT: - ACPI_STRUPR (acpi_gbl_db_args[1]); - status = acpi_db_display_objects (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_OPEN: - acpi_db_open_debug_file (acpi_gbl_db_args[1]); - break; - - case CMD_OWNER: - acpi_db_dump_namespace_by_owner (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_PREFIX: - acpi_db_set_scope (acpi_gbl_db_args[1]); - break; - - case CMD_REFERENCES: - acpi_db_find_references (acpi_gbl_db_args[1]); - break; - - case CMD_RESOURCES: - acpi_db_display_resources (acpi_gbl_db_args[1]); - break; - - case CMD_RESULTS: - acpi_db_display_results (); - break; - - case CMD_SET: - acpi_db_set_method_data (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); - break; - - case CMD_STATS: - status = acpi_db_display_statistics (acpi_gbl_db_args[1]); - break; - - case CMD_STOP: - return (AE_NOT_IMPLEMENTED); - - case CMD_TABLES: - acpi_db_display_table_info (acpi_gbl_db_args[1]); - break; - - case CMD_TERMINATE: - acpi_db_set_output_destination (ACPI_DB_REDIRECTABLE_OUTPUT); - acpi_ut_subsystem_shutdown (); - - /* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */ - - /* Acpi_initialize (NULL); */ - break; - - case CMD_THREADS: - acpi_db_create_execution_threads (acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); - break; - - case CMD_TREE: - acpi_db_display_calling_tree (); - break; - - case CMD_UNLOAD: - acpi_db_unload_acpi_table (acpi_gbl_db_args[1], acpi_gbl_db_args[2]); - break; - - case CMD_EXIT: - case CMD_QUIT: - if (op) - { - acpi_os_printf ("Method execution terminated\n"); - return (AE_CTRL_TERMINATE); - } - - if (!acpi_gbl_db_output_to_file) - { - acpi_dbg_level = DEBUG_DEFAULT; - } - - /* Shutdown */ - - /* Acpi_ut_subsystem_shutdown (); */ - acpi_db_close_debug_file (); - - acpi_gbl_db_terminate_threads = TRUE; - - return (AE_CTRL_TERMINATE); - - case CMD_NOT_FOUND: - default: - acpi_os_printf ("Unknown Command\n"); - return (AE_CTRL_TRUE); - } - - - /* Add all commands that come here to the history buffer */ - - acpi_db_add_to_history (input_buffer); - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_execute_thread - * - * PARAMETERS: Context - Not used - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void ACPI_SYSTEM_XFACE -acpi_db_execute_thread ( - void *context) -{ - acpi_status status = AE_OK; - acpi_status Mstatus; - - - while (status != AE_CTRL_TERMINATE) - { - acpi_gbl_method_executing = FALSE; - acpi_gbl_step_to_next_call = FALSE; - - Mstatus = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - if (ACPI_FAILURE (Mstatus)) - { - return; - } - - status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL); - - Mstatus = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - if (ACPI_FAILURE (Mstatus)) - { - return; - } - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_single_thread - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Debugger execute thread. Waits for a command line, then - * simply dispatches it. - * - ******************************************************************************/ - -void -acpi_db_single_thread ( - void) -{ - - acpi_gbl_method_executing = FALSE; - acpi_gbl_step_to_next_call = FALSE; - - (void) acpi_db_command_dispatch (acpi_gbl_db_line_buf, NULL, NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_user_commands - * - * PARAMETERS: Prompt - User prompt (depends on mode) - * Op - Current executing parse op - * - * RETURN: None - * - * DESCRIPTION: Command line execution for the AML debugger. Commands are - * matched and dispatched here. - * - ******************************************************************************/ - -acpi_status -acpi_db_user_commands ( - NATIVE_CHAR prompt, - acpi_parse_object *op) -{ - acpi_status status = AE_OK; - - - /* TBD: [Restructure] Need a separate command line buffer for step mode */ - - while (!acpi_gbl_db_terminate_threads) - { - /* Force output to console until a command is entered */ - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - - /* Different prompt if method is executing */ - - if (!acpi_gbl_method_executing) - { - acpi_os_printf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); - } - else - { - acpi_os_printf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); - } - - /* Get the user input line */ - - (void) acpi_os_get_line (acpi_gbl_db_line_buf); - - /* Check for single or multithreaded debug */ - - if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) - { - /* - * Signal the debug thread that we have a command to execute, - * and wait for the command to complete. - */ - status = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY); - if (ACPI_FAILURE (status)) - { - return (status); - } - - status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - if (ACPI_FAILURE (status)) - { - return (status); - } - } - else - { - /* Just call to the command line interpreter */ - - acpi_db_single_thread (); - } - } - - /* - * Only this thread (the original thread) should actually terminate the subsystem, - * because all the semaphores are deleted during termination - */ - status = acpi_terminate (); - return (status); -} - - -#endif /* ENABLE_DEBUGGER */ - diff -Nru a/drivers/acpi/debugger/dbstats.c b/drivers/acpi/debugger/dbstats.c --- a/drivers/acpi/debugger/dbstats.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,469 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbstats - Generation and display of ACPI table statistics - * $Revision: 59 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbstats") - -/* - * Statistics subcommands - */ -static ARGUMENT_INFO acpi_db_stat_types [] = -{ {"ALLOCATIONS"}, - {"OBJECTS"}, - {"MEMORY"}, - {"MISC"}, - {"TABLES"}, - {"SIZES"}, - {"STACK"}, - {NULL} /* Must be null terminated */ -}; - -#define CMD_STAT_ALLOCATIONS 0 -#define CMD_STAT_OBJECTS 1 -#define CMD_STAT_MEMORY 2 -#define CMD_STAT_MISC 3 -#define CMD_STAT_TABLES 4 -#define CMD_STAT_SIZES 5 -#define CMD_STAT_STACK 6 - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_enumerate_object - * - * PARAMETERS: Obj_desc - Object to be counted - * - * RETURN: None - * - * DESCRIPTION: Add this object to the global counts, by object type. - * Limited recursion handles subobjects and packages, and this - * is probably acceptable within the AML debugger only. - * - ******************************************************************************/ - -void -acpi_db_enumerate_object ( - acpi_operand_object *obj_desc) -{ - u32 i; - - - if (!obj_desc) - { - return; - } - - - /* Enumerate this object first */ - - acpi_gbl_num_objects++; - - if (obj_desc->common.type > INTERNAL_TYPE_NODE_MAX) - { - acpi_gbl_obj_type_count_misc++; - } - else - { - acpi_gbl_obj_type_count [obj_desc->common.type]++; - } - - /* Count the sub-objects */ - - switch (obj_desc->common.type) - { - case ACPI_TYPE_PACKAGE: - for (i = 0; i < obj_desc->package.count; i++) - { - acpi_db_enumerate_object (obj_desc->package.elements[i]); - } - break; - - case ACPI_TYPE_DEVICE: - acpi_db_enumerate_object (obj_desc->device.sys_handler); - acpi_db_enumerate_object (obj_desc->device.drv_handler); - acpi_db_enumerate_object (obj_desc->device.addr_handler); - break; - - case ACPI_TYPE_BUFFER_FIELD: - if (acpi_ns_get_secondary_object (obj_desc)) - { - acpi_gbl_obj_type_count [ACPI_TYPE_BUFFER_FIELD]++; - } - break; - - case ACPI_TYPE_REGION: - acpi_gbl_obj_type_count [INTERNAL_TYPE_REGION_FIELD ]++; - acpi_db_enumerate_object (obj_desc->region.addr_handler); - break; - - case ACPI_TYPE_POWER: - acpi_db_enumerate_object (obj_desc->power_resource.sys_handler); - acpi_db_enumerate_object (obj_desc->power_resource.drv_handler); - break; - - case ACPI_TYPE_PROCESSOR: - acpi_db_enumerate_object (obj_desc->processor.sys_handler); - acpi_db_enumerate_object (obj_desc->processor.drv_handler); - acpi_db_enumerate_object (obj_desc->processor.addr_handler); - break; - - case ACPI_TYPE_THERMAL: - acpi_db_enumerate_object (obj_desc->thermal_zone.sys_handler); - acpi_db_enumerate_object (obj_desc->thermal_zone.drv_handler); - acpi_db_enumerate_object (obj_desc->thermal_zone.addr_handler); - break; - - default: - break; - } -} - - -#ifndef PARSER_ONLY - -/******************************************************************************* - * - * FUNCTION: Acpi_db_classify_one_object - * - * PARAMETERS: Callback for Walk_namespace - * - * RETURN: Status - * - * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and - * the parent namespace node. - * - ******************************************************************************/ - -acpi_status -acpi_db_classify_one_object ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - acpi_namespace_node *node; - acpi_operand_object *obj_desc; - u32 type; - - - acpi_gbl_num_nodes++; - - node = (acpi_namespace_node *) obj_handle; - obj_desc = acpi_ns_get_attached_object (node); - - acpi_db_enumerate_object (obj_desc); - - type = node->type; - if (type > INTERNAL_TYPE_NODE_MAX) - { - acpi_gbl_node_type_count_misc++; - } - - else - { - acpi_gbl_node_type_count [type]++; - } - - return AE_OK; - - - /* TBD: These need to be counted during the initial parsing phase */ - /* - if (Acpi_ps_is_named_op (Op->Opcode)) - { - Num_nodes++; - } - - if (Is_method) - { - Num_method_elements++; - } - - Num_grammar_elements++; - Op = Acpi_ps_get_depth_next (Root, Op); - - Size_of_parse_tree = (Num_grammar_elements - Num_method_elements) * (u32) sizeof (acpi_parse_object); - Size_of_method_trees = Num_method_elements * (u32) sizeof (acpi_parse_object); - Size_of_node_entries = Num_nodes * (u32) sizeof (acpi_namespace_node); - Size_of_acpi_objects = Num_nodes * (u32) sizeof (acpi_operand_object); - - */ -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_count_namespace_objects - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Count and classify the entire namespace, including all - * namespace nodes and attached objects. - * - ******************************************************************************/ - -void -acpi_db_count_namespace_objects ( - void) -{ - u32 i; - - - acpi_gbl_num_nodes = 0; - acpi_gbl_num_objects = 0; - - acpi_gbl_obj_type_count_misc = 0; - for (i = 0; i < (INTERNAL_TYPE_NODE_MAX -1); i++) - { - acpi_gbl_obj_type_count [i] = 0; - acpi_gbl_node_type_count [i] = 0; - } - - (void) acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_db_classify_one_object, NULL, NULL); -} - -#endif - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_display_statistics - * - * PARAMETERS: Type_arg - Subcommand - * - * RETURN: Status - * - * DESCRIPTION: Display various statistics - * - ******************************************************************************/ - -acpi_status -acpi_db_display_statistics ( - NATIVE_CHAR *type_arg) -{ - u32 i; - u32 type; - u32 size; -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - u32 outstanding; -#endif - - - if (!acpi_gbl_DSDT) - { - acpi_os_printf ("*** Warning: There is no DSDT loaded\n"); - } - - if (!type_arg) - { - acpi_os_printf ("The following subcommands are available:\n ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n"); - return (AE_OK); - } - - ACPI_STRUPR (type_arg); - type = acpi_db_match_argument (type_arg, acpi_db_stat_types); - if (type == (u32) -1) - { - acpi_os_printf ("Invalid or unsupported argument\n"); - return (AE_OK); - } - - - switch (type) - { -#ifndef PARSER_ONLY - case CMD_STAT_ALLOCATIONS: -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_ut_dump_allocation_info (); -#endif - break; -#endif - - case CMD_STAT_TABLES: - - acpi_os_printf ("ACPI Table Information:\n\n"); - if (acpi_gbl_DSDT) - { - acpi_os_printf ("DSDT Length:................% 7ld (%X)\n", acpi_gbl_DSDT->length, acpi_gbl_DSDT->length); - } - break; - - case CMD_STAT_OBJECTS: - -#ifndef PARSER_ONLY - - acpi_db_count_namespace_objects (); - - acpi_os_printf ("\n_objects defined in the current namespace:\n\n"); - - acpi_os_printf ("%16.16s % 10.10s % 10.10s\n", "ACPI_TYPE", "NODES", "OBJECTS"); - - for (i = 0; i < INTERNAL_TYPE_NODE_MAX; i++) - { - acpi_os_printf ("%16.16s % 10ld% 10ld\n", acpi_ut_get_type_name (i), - acpi_gbl_node_type_count [i], acpi_gbl_obj_type_count [i]); - } - acpi_os_printf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown", - acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc); - - acpi_os_printf ("%16.16s % 10ld% 10ld\n", "TOTALS:", - acpi_gbl_num_nodes, acpi_gbl_num_objects); - -#endif - break; - - case CMD_STAT_MEMORY: - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_os_printf ("\n----Object and Cache Statistics---------------------------------------------\n"); - - for (i = 0; i < ACPI_NUM_MEM_LISTS; i++) - { - acpi_os_printf ("\n%s\n", acpi_gbl_memory_lists[i].list_name); - - if (acpi_gbl_memory_lists[i].max_cache_depth > 0) - { - acpi_os_printf (" Cache: [Depth Max Avail Size] % 7d % 7d % 7d % 7d B\n", - acpi_gbl_memory_lists[i].cache_depth, - acpi_gbl_memory_lists[i].max_cache_depth, - acpi_gbl_memory_lists[i].max_cache_depth - acpi_gbl_memory_lists[i].cache_depth, - (acpi_gbl_memory_lists[i].cache_depth * acpi_gbl_memory_lists[i].object_size)); - - acpi_os_printf (" Cache: [Requests Hits Misses Obj_size] % 7d % 7d % 7d % 7d B\n", - acpi_gbl_memory_lists[i].cache_requests, - acpi_gbl_memory_lists[i].cache_hits, - acpi_gbl_memory_lists[i].cache_requests - acpi_gbl_memory_lists[i].cache_hits, - acpi_gbl_memory_lists[i].object_size); - } - - outstanding = acpi_gbl_memory_lists[i].total_allocated - - acpi_gbl_memory_lists[i].total_freed - - acpi_gbl_memory_lists[i].cache_depth; - - if (acpi_gbl_memory_lists[i].object_size) - { - size = ACPI_ROUND_UP_TO_1K (outstanding * acpi_gbl_memory_lists[i].object_size); - } - else - { - size = ACPI_ROUND_UP_TO_1K (acpi_gbl_memory_lists[i].current_total_size); - } - - acpi_os_printf (" Mem: [Alloc Free Outstanding Size] % 7d % 7d % 7d % 7d Kb\n", - acpi_gbl_memory_lists[i].total_allocated, - acpi_gbl_memory_lists[i].total_freed, - outstanding, size); - } -#endif - - break; - - case CMD_STAT_MISC: - - acpi_os_printf ("\n_miscellaneous Statistics:\n\n"); - acpi_os_printf ("Calls to Acpi_ps_find:.. ........% 7ld\n", acpi_gbl_ps_find_count); - acpi_os_printf ("Calls to Acpi_ns_lookup:..........% 7ld\n", acpi_gbl_ns_lookup_count); - - acpi_os_printf ("\n"); - - acpi_os_printf ("Mutex usage:\n\n"); - for (i = 0; i < NUM_MTX; i++) - { - acpi_os_printf ("%-28s: % 7ld\n", acpi_ut_get_mutex_name (i), acpi_gbl_acpi_mutex_info[i].use_count); - } - break; - - - case CMD_STAT_SIZES: - - acpi_os_printf ("\n_internal object sizes:\n\n"); - - acpi_os_printf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON)); - acpi_os_printf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER)); - acpi_os_printf ("String %3d\n", sizeof (ACPI_OBJECT_STRING)); - acpi_os_printf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER)); - acpi_os_printf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE)); - acpi_os_printf ("Buffer_field %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD)); - acpi_os_printf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE)); - acpi_os_printf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT)); - acpi_os_printf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD)); - acpi_os_printf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX)); - acpi_os_printf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION)); - acpi_os_printf ("Power_resource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE)); - acpi_os_printf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR)); - acpi_os_printf ("Thermal_zone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE)); - acpi_os_printf ("Region_field %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD)); - acpi_os_printf ("Bank_field %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD)); - acpi_os_printf ("Index_field %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD)); - acpi_os_printf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE)); - acpi_os_printf ("Notify_handler %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER)); - acpi_os_printf ("Addr_handler %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER)); - acpi_os_printf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA)); - acpi_os_printf ("Data %3d\n", sizeof (ACPI_OBJECT_DATA)); - - acpi_os_printf ("\n"); - - acpi_os_printf ("Parse_object %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON)); - acpi_os_printf ("Parse_object_named %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED)); - acpi_os_printf ("Parse_object_asl %3d\n", sizeof (ACPI_PARSE_OBJ_ASL)); - acpi_os_printf ("Operand_object %3d\n", sizeof (acpi_operand_object)); - acpi_os_printf ("Namespace_node %3d\n", sizeof (acpi_namespace_node)); - - break; - - - case CMD_STAT_STACK: -#if defined(ACPI_DEBUG) - - size = (u32) (acpi_gbl_entry_stack_pointer - acpi_gbl_lowest_stack_pointer); - - acpi_os_printf ("\n_subsystem Stack Usage:\n\n"); - acpi_os_printf ("Entry Stack Pointer %X\n", acpi_gbl_entry_stack_pointer); - acpi_os_printf ("Lowest Stack Pointer %X\n", acpi_gbl_lowest_stack_pointer); - acpi_os_printf ("Stack Use %X (%d)\n", size, size); - acpi_os_printf ("Deepest Procedure Nesting %d\n", acpi_gbl_deepest_nesting); -#endif - break; - - default: - break; - } - - acpi_os_printf ("\n"); - return (AE_OK); -} - - -#endif /* ENABLE_DEBUGGER */ diff -Nru a/drivers/acpi/debugger/dbutils.c b/drivers/acpi/debugger/dbutils.c --- a/drivers/acpi/debugger/dbutils.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,380 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbutils - AML debugger utilities - * $Revision: 55 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "acdebug.h" -#include "acdispat.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbutils") - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_set_output_destination - * - * PARAMETERS: Output_flags - Current flags word - * - * RETURN: None - * - * DESCRIPTION: Set the current destination for debugger output. Alos sets - * the debug output level accordingly. - * - ******************************************************************************/ - -void -acpi_db_set_output_destination ( - u32 output_flags) -{ - - acpi_gbl_db_output_flags = (u8) output_flags; - - if ((output_flags & ACPI_DB_REDIRECTABLE_OUTPUT) && acpi_gbl_db_output_to_file) { - acpi_dbg_level = acpi_gbl_db_debug_level; - } - else { - acpi_dbg_level = acpi_gbl_db_console_debug_level; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_buffer - * - * PARAMETERS: Address - Pointer to the buffer - * - * RETURN: None - * - * DESCRIPTION: Print a portion of a buffer - * - ******************************************************************************/ - -void -acpi_db_dump_buffer ( - u32 address) -{ - - acpi_os_printf ("\n_location %X:\n", address); - - acpi_dbg_level |= ACPI_LV_TABLES; - acpi_ut_dump_buffer (ACPI_TO_POINTER (address), 64, DB_BYTE_DISPLAY, ACPI_UINT32_MAX); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_dump_object - * - * PARAMETERS: Obj_desc - External ACPI object to dump - * Level - Nesting level. - * - * RETURN: None - * - * DESCRIPTION: Dump the contents of an ACPI external object - * - ******************************************************************************/ - -void -acpi_db_dump_object ( - acpi_object *obj_desc, - u32 level) -{ - u32 i; - - - if (!obj_desc) { - acpi_os_printf ("[Null Object]\n"); - return; - } - - for (i = 0; i < level; i++) { - acpi_os_printf (" "); - } - - switch (obj_desc->type) { - case ACPI_TYPE_ANY: - - acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle); - break; - - - case ACPI_TYPE_INTEGER: - - acpi_os_printf ("[Integer] = %8.8X%8.8X\n", - ACPI_HIDWORD (obj_desc->integer.value), - ACPI_LODWORD (obj_desc->integer.value)); - break; - - - case ACPI_TYPE_STRING: - - acpi_os_printf ("[String] Value: "); - for (i = 0; i < obj_desc->string.length; i++) { - acpi_os_printf ("%c", obj_desc->string.pointer[i]); - } - acpi_os_printf ("\n"); - break; - - - case ACPI_TYPE_BUFFER: - - acpi_os_printf ("[Buffer] Length %.2X = ", obj_desc->buffer.length); - acpi_ut_dump_buffer ((u8 *) obj_desc->buffer.pointer, obj_desc->buffer.length, DB_DWORD_DISPLAY, _COMPONENT); - break; - - - case ACPI_TYPE_PACKAGE: - - acpi_os_printf ("[Package] Contains %d Elements: \n", obj_desc->package.count); - - for (i = 0; i < obj_desc->package.count; i++) { - acpi_db_dump_object (&obj_desc->package.elements[i], level+1); - } - break; - - - case INTERNAL_TYPE_REFERENCE: - - acpi_os_printf ("[Object Reference] = %p\n", obj_desc->reference.handle); - break; - - - case ACPI_TYPE_PROCESSOR: - - acpi_os_printf ("[Processor]\n"); - break; - - - case ACPI_TYPE_POWER: - - acpi_os_printf ("[Power Resource]\n"); - break; - - - default: - - acpi_os_printf ("[Unknown Type] %X \n", obj_desc->type); - break; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_prep_namestring - * - * PARAMETERS: Name - String to prepare - * - * RETURN: None - * - * DESCRIPTION: Translate all forward slashes and dots to backslashes. - * - ******************************************************************************/ - -void -acpi_db_prep_namestring ( - NATIVE_CHAR *name) -{ - - - if (!name) { - return; - } - - ACPI_STRUPR (name); - - /* Convert a leading forward slash to a backslash */ - - if (*name == '/') { - *name = '\\'; - } - - /* Ignore a leading backslash, this is the root prefix */ - - if (*name == '\\') { - name++; - } - - /* Convert all slash path separators to dots */ - - while (*name) { - if ((*name == '/') || - (*name == '\\')) { - *name = '.'; - } - - name++; - } -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_second_pass_parse - * - * PARAMETERS: Root - Root of the parse tree - * - * RETURN: Status - * - * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until - * second pass to parse the control methods - * - ******************************************************************************/ - -acpi_status -acpi_db_second_pass_parse ( - acpi_parse_object *root) -{ - acpi_parse_object *op = root; - acpi_parse_object *method; - acpi_parse_object *search_op; - acpi_parse_object *start_op; - acpi_status status = AE_OK; - u32 base_aml_offset; - acpi_walk_state *walk_state; - - - ACPI_FUNCTION_ENTRY (); - - - acpi_os_printf ("Pass two parse ....\n"); - - while (op) { - if (op->common.aml_opcode == AML_METHOD_OP) { - method = op; - - /* Create a new walk state for the parse */ - - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, - NULL, NULL, NULL); - if (!walk_state) { - return (AE_NO_MEMORY); - } - - /* Init the Walk State */ - - walk_state->parser_state.aml = - walk_state->parser_state.aml_start = method->named.data; - walk_state->parser_state.aml_end = - walk_state->parser_state.pkg_end = method->named.data + method->named.length; - walk_state->parser_state.start_scope = op; - - walk_state->descending_callback = acpi_ds_load1_begin_op; - walk_state->ascending_callback = acpi_ds_load1_end_op; - - /* Perform the AML parse */ - - status = acpi_ps_parse_aml (walk_state); - - base_aml_offset = (method->common.value.arg)->common.aml_offset + 1; - start_op = (method->common.value.arg)->common.next; - search_op = start_op; - - while (search_op) { - search_op->common.aml_offset += base_aml_offset; - search_op = acpi_ps_get_depth_next (start_op, search_op); - } - } - - if (op->common.aml_opcode == AML_REGION_OP) { - /* TBD: [Investigate] this isn't quite the right thing to do! */ - /* - * - * Method = (ACPI_DEFERRED_OP *) Op; - * Status = Acpi_ps_parse_aml (Op, Method->Body, Method->Body_length); - */ - } - - if (ACPI_FAILURE (status)) { - break; - } - - op = acpi_ps_get_depth_next (root, op); - } - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_local_ns_lookup - * - * PARAMETERS: Name - Name to lookup - * - * RETURN: Pointer to a namespace node - * - * DESCRIPTION: Lookup a name in the ACPI namespace - * - * Note: Currently begins search from the root. Could be enhanced to use - * the current prefix (scope) node as the search beginning point. - * - ******************************************************************************/ - -acpi_namespace_node * -acpi_db_local_ns_lookup ( - NATIVE_CHAR *name) -{ - NATIVE_CHAR *internal_path; - acpi_status status; - acpi_namespace_node *node = NULL; - - - acpi_db_prep_namestring (name); - - /* Build an internal namestring */ - - status = acpi_ns_internalize_name (name, &internal_path); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Invalid namestring: %s\n", name); - return (NULL); - } - - /* - * Lookup the name. - * (Uses root node as the search starting point) - */ - status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, - ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not locate name: %s %s\n", name, acpi_format_exception (status)); - } - - ACPI_MEM_FREE (internal_path); - return (node); -} - - -#endif /* ENABLE_DEBUGGER */ - - diff -Nru a/drivers/acpi/debugger/dbxface.c b/drivers/acpi/debugger/dbxface.c --- a/drivers/acpi/debugger/dbxface.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,388 +0,0 @@ -/******************************************************************************* - * - * Module Name: dbxface - AML Debugger external interfaces - * $Revision: 59 $ - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2002, R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "amlcode.h" -#include "acdebug.h" - - -#ifdef ENABLE_DEBUGGER - -#define _COMPONENT ACPI_DEBUGGER - ACPI_MODULE_NAME ("dbxface") - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_single_step - * - * PARAMETERS: Walk_state - Current walk - * Op - Current executing op - * Opcode_class - Class of the current AML Opcode - * - * RETURN: Status - * - * DESCRIPTION: Called just before execution of an AML opcode. - * - ******************************************************************************/ - -acpi_status -acpi_db_single_step ( - acpi_walk_state *walk_state, - acpi_parse_object *op, - u32 opcode_class) -{ - acpi_parse_object *next; - acpi_status status = AE_OK; - u32 original_debug_level; - acpi_parse_object *display_op; - acpi_parse_object *parent_op; - - - ACPI_FUNCTION_ENTRY (); - - /* Check for single-step breakpoint */ - - if (walk_state->method_breakpoint && - (walk_state->method_breakpoint <= op->common.aml_offset)) { - /* Check if the breakpoint has been reached or passed */ - /* Hit the breakpoint, resume single step, reset breakpoint */ - - acpi_os_printf ("***Break*** at AML offset %X\n", op->common.aml_offset); - acpi_gbl_cm_single_step = TRUE; - acpi_gbl_step_to_next_call = FALSE; - walk_state->method_breakpoint = 0; - } - - /* Check for user breakpoint (Must be on exact Aml offset) */ - - else if (walk_state->user_breakpoint && - (walk_state->user_breakpoint == op->common.aml_offset)) { - acpi_os_printf ("***User_breakpoint*** at AML offset %X\n", op->common.aml_offset); - acpi_gbl_cm_single_step = TRUE; - acpi_gbl_step_to_next_call = FALSE; - walk_state->method_breakpoint = 0; - } - - - /* - * Check if this is an opcode that we are interested in -- - * namely, opcodes that have arguments - */ - if (op->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { - return (AE_OK); - } - - switch (opcode_class) { - case AML_CLASS_UNKNOWN: - case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */ - return (AE_OK); - - default: - /* All other opcodes -- continue */ - break; - } - - /* - * Under certain debug conditions, display this opcode and its operands - */ - if ((acpi_gbl_db_output_to_file) || - (acpi_gbl_cm_single_step) || - (acpi_dbg_level & ACPI_LV_PARSE)) { - if ((acpi_gbl_db_output_to_file) || - (acpi_dbg_level & ACPI_LV_PARSE)) { - acpi_os_printf ("\n[Aml_debug] Next AML Opcode to execute:\n"); - } - - /* - * Display this op (and only this op - zero out the NEXT field temporarily, - * and disable parser trace output for the duration of the display because - * we don't want the extraneous debug output) - */ - original_debug_level = acpi_dbg_level; - acpi_dbg_level &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS); - next = op->common.next; - op->common.next = NULL; - - - display_op = op; - parent_op = op->common.parent; - if (parent_op) { - if ((walk_state->control_state) && - (walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING)) { - /* - * We are executing the predicate of an IF or WHILE statement - * Search upwards for the containing IF or WHILE so that the - * entire predicate can be displayed. - */ - while (parent_op) { - if ((parent_op->common.aml_opcode == AML_IF_OP) || - (parent_op->common.aml_opcode == AML_WHILE_OP)) { - display_op = parent_op; - break; - } - parent_op = parent_op->common.parent; - } - } - else { - while (parent_op) { - if ((parent_op->common.aml_opcode == AML_IF_OP) || - (parent_op->common.aml_opcode == AML_ELSE_OP) || - (parent_op->common.aml_opcode == AML_SCOPE_OP) || - (parent_op->common.aml_opcode == AML_METHOD_OP) || - (parent_op->common.aml_opcode == AML_WHILE_OP)) { - break; - } - display_op = parent_op; - parent_op = parent_op->common.parent; - } - } - } - - /* Now we can display it */ - - acpi_db_display_op (walk_state, display_op, ACPI_UINT32_MAX); - - if ((op->common.aml_opcode == AML_IF_OP) || - (op->common.aml_opcode == AML_WHILE_OP)) { - if (walk_state->control_state->common.value) { - acpi_os_printf ("Predicate = [True], IF block was executed\n"); - } - else { - acpi_os_printf ("Predicate = [False], Skipping IF block\n"); - } - } - - else if (op->common.aml_opcode == AML_ELSE_OP) { - acpi_os_printf ("Predicate = [False], ELSE block was executed\n"); - } - - /* Restore everything */ - - op->common.next = next; - acpi_os_printf ("\n"); - acpi_dbg_level = original_debug_level; - } - - /* If we are not single stepping, just continue executing the method */ - - if (!acpi_gbl_cm_single_step) { - return (AE_OK); - } - - /* - * If we are executing a step-to-call command, - * Check if this is a method call. - */ - if (acpi_gbl_step_to_next_call) { - if (op->common.aml_opcode != AML_INT_METHODCALL_OP) { - /* Not a method call, just keep executing */ - - return (AE_OK); - } - - /* Found a method call, stop executing */ - - acpi_gbl_step_to_next_call = FALSE; - } - - /* - * If the next opcode is a method call, we will "step over" it - * by default. - */ - if (op->common.aml_opcode == AML_INT_METHODCALL_OP) { - acpi_gbl_cm_single_step = FALSE; /* No more single step while executing called method */ - - /* Set the breakpoint on/before the call, it will stop execution as soon as we return */ - - walk_state->method_breakpoint = 1; /* Must be non-zero! */ - } - - - /* TBD: [Investigate] what are the namespace locking issues here */ - - /* Acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); */ - - /* Go into the command loop and await next user command */ - - acpi_gbl_method_executing = TRUE; - status = AE_CTRL_TRUE; - while (status == AE_CTRL_TRUE) { - if (acpi_gbl_debugger_configuration == DEBUGGER_MULTI_THREADED) { - /* Handshake with the front-end that gets user command lines */ - - status = acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - if (ACPI_FAILURE (status)) { - return (status); - } - status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - if (ACPI_FAILURE (status)) { - return (status); - } - } - - else { - /* Single threaded, we must get a command line ourselves */ - - /* Force output to console until a command is entered */ - - acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT); - - /* Different prompt if method is executing */ - - if (!acpi_gbl_method_executing) { - acpi_os_printf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); - } - else { - acpi_os_printf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); - } - - /* Get the user input line */ - - (void) acpi_os_get_line (acpi_gbl_db_line_buf); - } - - status = acpi_db_command_dispatch (acpi_gbl_db_line_buf, walk_state, op); - } - - /* Acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); */ - - /* User commands complete, continue execution of the interrupted method */ - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_initialize - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Init and start debugger - * - ******************************************************************************/ - -acpi_status -acpi_db_initialize (void) -{ - acpi_status status; - - - /* Init globals */ - - acpi_gbl_db_buffer = NULL; - acpi_gbl_db_filename = NULL; - acpi_gbl_db_output_to_file = FALSE; - - acpi_gbl_db_debug_level = ACPI_LV_VERBOSITY2; - acpi_gbl_db_console_debug_level = NORMAL_DEFAULT | ACPI_LV_TABLES; - acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; - - acpi_gbl_db_opt_tables = FALSE; - acpi_gbl_db_opt_disasm = FALSE; - acpi_gbl_db_opt_stats = FALSE; - acpi_gbl_db_opt_verbose = TRUE; - acpi_gbl_db_opt_ini_methods = TRUE; - - acpi_gbl_db_buffer = acpi_os_allocate (ACPI_DEBUG_BUFFER_SIZE); - if (!acpi_gbl_db_buffer) { - return (AE_NO_MEMORY); - } - ACPI_MEMSET (acpi_gbl_db_buffer, 0, ACPI_DEBUG_BUFFER_SIZE); - - /* Initial scope is the root */ - - acpi_gbl_db_scope_buf [0] = '\\'; - acpi_gbl_db_scope_buf [1] = 0; - acpi_gbl_db_scope_node = acpi_gbl_root_node; - - /* - * If configured for multi-thread support, the debug executor runs in - * a separate thread so that the front end can be in another address - * space, environment, or even another machine. - */ - if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) { - /* These were created with one unit, grab it */ - - status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not get debugger mutex\n"); - return (status); - } - status = acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not get debugger mutex\n"); - return (status); - } - - /* Create the debug execution thread to execute commands */ - - status = acpi_os_queue_for_execution (0, acpi_db_execute_thread, NULL); - if (ACPI_FAILURE (status)) { - acpi_os_printf ("Could not start debugger thread\n"); - return (status); - } - } - - if (!acpi_gbl_db_opt_verbose) { - acpi_gbl_db_disasm_indent = " "; - acpi_gbl_db_opt_disasm = TRUE; - acpi_gbl_db_opt_stats = FALSE; - } - - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_db_terminate - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Stop debugger - * - ******************************************************************************/ - -void -acpi_db_terminate (void) -{ - - if (acpi_gbl_db_table_ptr) { - acpi_os_free (acpi_gbl_db_table_ptr); - } - if (acpi_gbl_db_buffer) { - acpi_os_free (acpi_gbl_db_buffer); - } -} - - -#endif /* ENABLE_DEBUGGER */ diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c --- a/drivers/acpi/ec.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,736 +0,0 @@ -/* - * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 28 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_EC_COMPONENT -ACPI_MODULE_NAME ("acpi_ec") - -#define PREFIX "ACPI: " - - -#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ -#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ -#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ - -#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ -#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ - -#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ -#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ - -#define ACPI_EC_COMMAND_READ 0x80 -#define ACPI_EC_COMMAND_WRITE 0x81 -#define ACPI_EC_COMMAND_QUERY 0x84 - -static int acpi_ec_add (struct acpi_device *device); -static int acpi_ec_remove (struct acpi_device *device, int type); -static int acpi_ec_start (struct acpi_device *device); -static int acpi_ec_stop (struct acpi_device *device, int type); - -static struct acpi_driver acpi_ec_driver = { - name: ACPI_EC_DRIVER_NAME, - class: ACPI_EC_CLASS, - ids: ACPI_EC_HID, - ops: { - add: acpi_ec_add, - remove: acpi_ec_remove, - start: acpi_ec_start, - stop: acpi_ec_stop, - }, -}; - -struct acpi_ec { - acpi_handle handle; - unsigned long gpe_bit; - unsigned long status_port; - unsigned long command_port; - unsigned long data_port; - unsigned long global_lock; - spinlock_t lock; -}; - - -/* -------------------------------------------------------------------------- - Transaction Management - -------------------------------------------------------------------------- */ - -static int -acpi_ec_wait ( - struct acpi_ec *ec, - u8 event) -{ - u8 acpi_ec_status = 0; - u32 i = ACPI_EC_UDELAY_COUNT; - - if (!ec) - return -EINVAL; - - /* Poll the EC status register waiting for the event to occur. */ - switch (event) { - case ACPI_EC_EVENT_OBF: - do { - acpi_ec_status = inb(ec->status_port); - if (acpi_ec_status & ACPI_EC_FLAG_OBF) - return 0; - udelay(ACPI_EC_UDELAY); - } while (--i>0); - break; - case ACPI_EC_EVENT_IBE: - do { - acpi_ec_status = inb(ec->status_port); - if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) - return 0; - udelay(ACPI_EC_UDELAY); - } while (--i>0); - break; - default: - return -EINVAL; - } - - return -ETIME; -} - - -static int -acpi_ec_read ( - struct acpi_ec *ec, - u8 address, - u8 *data) -{ - acpi_status status = AE_OK; - int result = 0; - unsigned long flags = 0; - u32 glk = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_read"); - - if (!ec || !data) - return_VALUE(-EINVAL); - - *data = 0; - - if (ec->global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - } - - spin_lock_irqsave(&ec->lock, flags); - - outb(ACPI_EC_COMMAND_READ, ec->command_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (0 != result) - goto end; - - outb(address, ec->data_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (0 != result) - goto end; - - *data = inb(ec->data_port); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", - *data, address)); - -end: - spin_unlock_irqrestore(&ec->lock, flags); - - if (ec->global_lock) - acpi_release_global_lock(glk); - - return_VALUE(result); -} - - -static int -acpi_ec_write ( - struct acpi_ec *ec, - u8 address, - u8 data) -{ - int result = 0; - acpi_status status = AE_OK; - unsigned long flags = 0; - u32 glk = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_write"); - - if (!ec) - return_VALUE(-EINVAL); - - if (ec->global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - } - - spin_lock_irqsave(&ec->lock, flags); - - outb(ACPI_EC_COMMAND_WRITE, ec->command_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (0 != result) - goto end; - - outb(address, ec->data_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (0 != result) - goto end; - - outb(data, ec->data_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (0 != result) - goto end; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", - data, address)); - -end: - spin_unlock_irqrestore(&ec->lock, flags); - - if (ec->global_lock) - acpi_release_global_lock(glk); - - return_VALUE(result); -} - - -static int -acpi_ec_query ( - struct acpi_ec *ec, - u8 *data) -{ - int result = 0; - acpi_status status = AE_OK; - unsigned long flags = 0; - u32 glk = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_query"); - - if (!ec || !data) - return_VALUE(-EINVAL); - - *data = 0; - - if (ec->global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - } - - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ - - spin_lock_irqsave(&ec->lock, flags); - - outb(ACPI_EC_COMMAND_QUERY, ec->command_port); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (0 != result) - goto end; - - *data = inb(ec->data_port); - if (!*data) - result = -ENODATA; - -end: - spin_unlock_irqrestore(&ec->lock, flags); - - if (ec->global_lock) - acpi_release_global_lock(glk); - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - Event Management - -------------------------------------------------------------------------- */ - -struct acpi_ec_query_data { - acpi_handle handle; - u8 data; -}; - - -static void -acpi_ec_gpe_query ( - void *data) -{ - struct acpi_ec_query_data *query_data = NULL; - static char object_name[5] = {'_','Q','0','0','\0'}; - const char hex[] = {'0','1','2','3','4','5','6','7', - '8','9','A','B','C','D','E','F'}; - - ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); - - if (!data) - return; - - query_data = (struct acpi_ec_query_data *) data; - - object_name[2] = hex[((query_data->data >> 4) & 0x0F)]; - object_name[3] = hex[(query_data->data & 0x0F)]; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); - - acpi_evaluate(query_data->handle, object_name, NULL, NULL); - - kfree(query_data); - - return; -} - - -static void -acpi_ec_gpe_handler ( - void *data) -{ - acpi_status status = AE_OK; - struct acpi_ec *ec = (struct acpi_ec *) data; - u8 value = 0; - unsigned long flags = 0; - struct acpi_ec_query_data *query_data = NULL; - - if (!ec) - return; - - spin_lock_irqsave(&ec->lock, flags); - value = inb(ec->command_port); - spin_unlock_irqrestore(&ec->lock, flags); - - /* TBD: Implement asynch events! - * NOTE: All we care about are EC-SCI's. Other EC events are - * handled via polling (yuck!). This is because some systems - * treat EC-SCIs as level (versus EDGE!) triggered, preventing - * a purely interrupt-driven approach (grumble, grumble). - */ - - if (!(value & ACPI_EC_FLAG_SCI)) - return; - - if (0 != acpi_ec_query(ec, &value)) - return; - - query_data = kmalloc(sizeof(struct acpi_ec_query_data), GFP_ATOMIC); - if (!query_data) - return; - query_data->handle = ec->handle; - query_data->data = value; - - status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, - acpi_ec_gpe_query, query_data); - if (ACPI_FAILURE(status)) - kfree(query_data); - - return; -} - - -/* -------------------------------------------------------------------------- - Address Space Management - -------------------------------------------------------------------------- */ - -static acpi_status -acpi_ec_space_setup ( - acpi_handle region_handle, - u32 function, - void *handler_context, - void **return_context) -{ - /* - * The EC object is in the handler context and is needed - * when calling the acpi_ec_space_handler. - */ - *return_context = handler_context; - - return AE_OK; -} - - -static acpi_status -acpi_ec_space_handler ( - u32 function, - ACPI_PHYSICAL_ADDRESS address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context) -{ - int result = 0; - struct acpi_ec *ec = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_space_handler"); - - if ((address > 0xFF) || (bit_width != 8) || !value || !handler_context) - return_VALUE(AE_BAD_PARAMETER); - - ec = (struct acpi_ec *) handler_context; - - switch (function) { - case ACPI_READ: - result = acpi_ec_read(ec, (u8) address, (u8*) value); - break; - case ACPI_WRITE: - result = acpi_ec_write(ec, (u8) address, (u8) *value); - break; - default: - result = -EINVAL; - break; - } - - switch (result) { - case -EINVAL: - return_VALUE(AE_BAD_PARAMETER); - break; - case -ENODEV: - return_VALUE(AE_NOT_FOUND); - break; - case -ETIME: - return_VALUE(AE_TIME); - break; - default: - return_VALUE(AE_OK); - } - -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_ec_dir = NULL; - - -static int -acpi_ec_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_ec *ec = (struct acpi_ec *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_read_info"); - - if (!ec || (off != 0)) - goto end; - - p += sprintf(p, "gpe bit: 0x%02x\n", - (u32) ec->gpe_bit); - p += sprintf(p, "ports: 0x%02x, 0x%02x\n", - (u32) ec->status_port, (u32) ec->data_port); - p += sprintf(p, "use global lock: %s\n", - ec->global_lock?"yes":"no"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_ec_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); - - if (!acpi_ec_dir) { - acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); - if (!acpi_ec_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_ec_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - entry = create_proc_read_entry(ACPI_EC_FILE_INFO, S_IRUGO, - acpi_device_dir(device), acpi_ec_read_info, - acpi_driver_data(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Unable to create '%s' fs entry\n", - ACPI_EC_FILE_INFO)); - - return_VALUE(0); -} - - -static int -acpi_ec_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_ec_remove_fs"); - - if (!acpi_ec_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_ec_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static int -acpi_ec_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_add"); - - if (!device) - return_VALUE(-EINVAL); - - ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); - if (!ec) - return_VALUE(-ENOMEM); - memset(ec, 0, sizeof(struct acpi_ec)); - - ec->handle = device->handle; - ec->lock = SPIN_LOCK_UNLOCKED; - sprintf(acpi_device_name(device), "%s", ACPI_EC_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_EC_CLASS); - acpi_driver_data(device) = ec; - - /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock); - - /* Get GPE bit assignment (EC events). */ - status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error obtaining GPE bit assignment\n")); - result = -ENODEV; - goto end; - } - - result = acpi_ec_add_fs(device); - if (0 != result) - goto end; - - printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", - acpi_device_name(device), acpi_device_bid(device), - (u32) ec->gpe_bit); - -end: - if (0 != result) - kfree(ec); - - return_VALUE(result); -} - - -static int -acpi_ec_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_ec *ec = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_remove"); - - if (!device) - return_VALUE(-EINVAL); - - ec = (struct acpi_ec *) acpi_driver_data(device); - - acpi_ec_remove_fs(device); - - kfree(ec); - - return_VALUE(0); -} - - -static int -acpi_ec_start ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_resource *resource = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_start"); - - if (!device) - return_VALUE(-EINVAL); - - ec = (struct acpi_ec *) acpi_driver_data(device); - - if (!ec) - return_VALUE(-EINVAL); - - /* - * Get I/O port addresses - */ - - status = acpi_get_current_resources(ec->handle, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); - return_VALUE(-ENODEV); - } - - resource = (acpi_resource *) buffer.pointer; - if (!resource || (resource->id != ACPI_RSTYPE_IO)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n")); - result = -ENODEV; - goto end; - } - ec->data_port = resource->data.io.min_base_address; - - resource = ACPI_NEXT_RESOURCE(resource); - if (!resource || (resource->id != ACPI_RSTYPE_IO)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid or missing resource\n")); - result = -ENODEV; - goto end; - } - ec->command_port = ec->status_port = resource->data.io.min_base_address; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", - (u32) ec->gpe_bit, (u32) ec->command_port, (u32) ec->data_port)); - - /* - * Install GPE handler - */ - - status = acpi_install_gpe_handler(ec->gpe_bit, - ACPI_EVENT_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - status = acpi_install_address_space_handler (ec->handle, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, - &acpi_ec_space_setup, ec); - if (ACPI_FAILURE(status)) { - acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); - return_VALUE(-ENODEV); - } -end: - kfree(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_ec_stop ( - struct acpi_device *device, - int type) -{ - acpi_status status = AE_OK; - struct acpi_ec *ec = NULL; - - ACPI_FUNCTION_TRACE("acpi_ec_stop"); - - if (!device) - return_VALUE(-EINVAL); - - ec = (struct acpi_ec *) acpi_driver_data(device); - - status = acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - status = acpi_remove_gpe_handler(ec->gpe_bit, &acpi_ec_gpe_handler); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -int __init -acpi_ec_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_init"); - - result = acpi_bus_register_driver(&acpi_ec_driver); - if (0 > result) { - remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -void __exit -acpi_ec_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_ec_exit"); - - result = acpi_bus_unregister_driver(&acpi_ec_driver); - if (0 == result) - remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); - - return_VOID; -} diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c --- a/drivers/acpi/fan.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,300 +0,0 @@ -/* - * acpi_fan.c - ACPI Fan Driver ($Revision: 25 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_FAN_COMPONENT -ACPI_MODULE_NAME ("acpi_fan") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - - -int acpi_fan_add (struct acpi_device *device); -int acpi_fan_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_fan_driver = { - name: ACPI_FAN_DRIVER_NAME, - class: ACPI_FAN_CLASS, - ids: ACPI_FAN_HID, - ops: { - add: acpi_fan_add, - remove: acpi_fan_remove, - }, -}; - -struct acpi_fan { - acpi_handle handle; -}; - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_fan_dir = NULL; - - -static int -acpi_fan_read_state ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_fan *fan = (struct acpi_fan *) data; - char *p = page; - int len = 0; - int state = 0; - - ACPI_FUNCTION_TRACE("acpi_fan_read_state"); - - if (!fan || (off != 0)) - goto end; - - if (0 != acpi_bus_get_power(fan->handle, &state)) - goto end; - - p += sprintf(p, "status: %s\n", - !state?"on":"off"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_fan_write_state ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_fan *fan = (struct acpi_fan *) data; - char state_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_fan_write_state"); - - if (!fan || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - - result = acpi_bus_set_power(fan->handle, - simple_strtoul(state_string, NULL, 0)); - if (0 != result) - return_VALUE(result); - - return_VALUE(count); -} - - -static int -acpi_fan_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_fan_add_fs"); - - if (!device) - return_VALUE(-EINVAL); - - if (!acpi_fan_dir) { - acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); - if (!acpi_fan_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_fan_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'status' [R/W] */ - entry = create_proc_entry(ACPI_FAN_FILE_STATE, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_FAN_FILE_STATE)); - else { - entry->read_proc = acpi_fan_read_state; - entry->write_proc = acpi_fan_write_state; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_fan_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_fan_remove_fs"); - - if (!acpi_fan_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -int -acpi_fan_add ( - struct acpi_device *device) -{ - int result = 0; - struct acpi_fan *fan = NULL; - int state = 0; - - ACPI_FUNCTION_TRACE("acpi_fan_add"); - - if (!device) - return_VALUE(-EINVAL); - - fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); - if (!fan) - return_VALUE(-ENOMEM); - memset(fan, 0, sizeof(struct acpi_fan)); - - fan->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_FAN_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_FAN_CLASS); - acpi_driver_data(device) = fan; - - result = acpi_bus_get_power(fan->handle, &state); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading power state\n")); - goto end; - } - - result = acpi_fan_add_fs(device); - if (0 != result) - goto end; - - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), - !device->power.state?"on":"off"); - -end: - if (0 != result) - kfree(fan); - - return_VALUE(result); -} - - -int -acpi_fan_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_fan *fan = NULL; - - ACPI_FUNCTION_TRACE("acpi_fan_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - fan = (struct acpi_fan *) acpi_driver_data(device); - - acpi_fan_remove_fs(device); - - kfree(fan); - - return_VALUE(0); -} - - -int __init -acpi_fan_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_fan_init"); - - result = acpi_bus_register_driver(&acpi_fan_driver); - if (0 > result) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -void __exit -acpi_fan_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_fan_exit"); - - result = acpi_bus_unregister_driver(&acpi_fan_driver); - if (0 == result) - remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); - - return_VOID; -} - - -module_init(acpi_fan_init); -module_exit(acpi_fan_exit); - diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,913 +0,0 @@ -/* - * acpi_osl.c - OS-dependent functions ($Revision: 1.2 $) - * - * Copyright (C) 2000 Andrew Henroid - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi.h" - -#ifdef CONFIG_ACPI_EFI -#include -u64 efi_mem_attributes (u64 phys_addr); -#endif - - -#define _COMPONENT ACPI_OS_SERVICES -ACPI_MODULE_NAME ("osl") - -#define PREFIX "ACPI: " - -typedef struct -{ - OSD_EXECUTION_CALLBACK function; - void *context; -} ACPI_OS_DPC; - - -#ifdef ENABLE_DEBUGGER -#include -/* stuff for debugger support */ -int acpi_in_debugger = 0; -extern NATIVE_CHAR line_buf[80]; -#endif /*ENABLE_DEBUGGER*/ - -static int acpi_irq_irq = 0; -static OSD_HANDLER acpi_irq_handler = NULL; -static void *acpi_irq_context = NULL; - - -acpi_status -acpi_os_initialize(void) -{ - /* - * Initialize PCI configuration space access, as we'll need to access - * it while walking the namespace (bus 0 and root bridges w/ _BBNs). - */ -#ifdef CONFIG_ACPI_PCI - pcibios_config_init(); - if (!pci_config_read || !pci_config_write) { - printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n"); - return AE_NULL_ENTRY; - } -#endif - - return AE_OK; -} - -acpi_status -acpi_os_terminate(void) -{ - if (acpi_irq_handler) { - acpi_os_remove_interrupt_handler(acpi_irq_irq, - acpi_irq_handler); - } - - return AE_OK; -} - -void -acpi_os_printf(const NATIVE_CHAR *fmt,...) -{ - va_list args; - va_start(args, fmt); - acpi_os_vprintf(fmt, args); - va_end(args); -} - -void -acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args) -{ - static char buffer[512]; - - vsprintf(buffer, fmt, args); - -#ifdef ENABLE_DEBUGGER - if (acpi_in_debugger) { - kdb_printf("%s", buffer); - } else { - printk("%s", buffer); - } -#else - printk("%s", buffer); -#endif -} - -void * -acpi_os_allocate(ACPI_SIZE size) -{ - return kmalloc(size, GFP_KERNEL); -} - -void * -acpi_os_callocate(ACPI_SIZE size) -{ - void *ptr = acpi_os_allocate(size); - if (ptr) - memset(ptr, 0, size); - - return ptr; -} - -void -acpi_os_free(void *ptr) -{ - kfree(ptr); -} - -acpi_status -acpi_os_get_root_pointer(u32 flags, ACPI_POINTER *addr) -{ -#ifdef CONFIG_ACPI_EFI - addr->pointer_type = ACPI_PHYSICAL_POINTER; - if (efi.acpi20) - addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi20); - else if (efi.acpi) - addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi); - else { - printk(KERN_ERR PREFIX "System description tables not found\n"); - return AE_NOT_FOUND; - } -#else - if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) { - printk(KERN_ERR PREFIX "System description tables not found\n"); - return AE_NOT_FOUND; - } -#endif /*CONFIG_ACPI_EFI*/ - - return AE_OK; -} - -acpi_status -acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, ACPI_SIZE size, void **virt) -{ -#ifdef CONFIG_ACPI_EFI - if (EFI_MEMORY_WB & efi_mem_attributes(phys)) { - *virt = phys_to_virt(phys); - } else { - *virt = ioremap(phys, size); - } -#else - if (phys > ULONG_MAX) { - printk(KERN_ERR PREFIX "Cannot map memory that high\n"); - return AE_BAD_PARAMETER; - } - /* - * ioremap checks to ensure this is in reserved space - */ - *virt = ioremap((unsigned long) phys, size); -#endif - - if (!*virt) - return AE_NO_MEMORY; - - return AE_OK; -} - -void -acpi_os_unmap_memory(void *virt, ACPI_SIZE size) -{ - iounmap(virt); -} - -acpi_status -acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys) -{ - if(!phys || !virt) - return AE_BAD_PARAMETER; - - *phys = virt_to_phys(virt); - - return AE_OK; -} - -acpi_status -acpi_os_table_override (acpi_table_header *existing_table, acpi_table_header **new_table) -{ - if (!existing_table || !new_table) - return AE_BAD_PARAMETER; - - *new_table = NULL; - return AE_OK; -} - -static void -acpi_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - (*acpi_irq_handler)(acpi_irq_context); -} - -acpi_status -acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) -{ -#ifdef CONFIG_IA64 - int vector; - - vector = acpi_irq_to_vector(irq); - if (vector < 0) { - printk(KERN_ERR PREFIX "SCI (IRQ%d) not registerd\n", irq); - return AE_OK; - } - irq = vector; -#endif - acpi_irq_irq = irq; - acpi_irq_handler = handler; - acpi_irq_context = context; - if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) { - printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); - return AE_NOT_ACQUIRED; - } - - return AE_OK; -} - -acpi_status -acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) -{ - if (acpi_irq_handler) { -#ifdef CONFIG_IA64 - irq = acpi_irq_to_vector(irq); -#endif - free_irq(irq, acpi_irq); - acpi_irq_handler = NULL; - } - - return AE_OK; -} - -/* - * Running in interpreter thread context, safe to sleep - */ - -void -acpi_os_sleep(u32 sec, u32 ms) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ * sec + (ms * HZ) / 1000); -} - -void -acpi_os_stall(u32 us) -{ - if (us > 10000) { - mdelay(us / 1000); - } - else { - udelay(us); - } -} - -acpi_status -acpi_os_read_port( - ACPI_IO_ADDRESS port, - void *value, - u32 width) -{ - u32 dummy; - - if (!value) - value = &dummy; - - switch (width) - { - case 8: - *(u8*) value = inb(port); - break; - case 16: - *(u16*) value = inw(port); - break; - case 32: - *(u32*) value = inl(port); - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_write_port( - ACPI_IO_ADDRESS port, - acpi_integer value, - u32 width) -{ - switch (width) - { - case 8: - outb(value, port); - break; - case 16: - outw(value, port); - break; - case 32: - outl(value, port); - break; - default: - BUG(); - } - - return AE_OK; -} - -acpi_status -acpi_os_read_memory( - ACPI_PHYSICAL_ADDRESS phys_addr, - void *value, - u32 width) -{ - u32 dummy; - void *virt_addr; - -#ifdef CONFIG_ACPI_EFI - int iomem = 0; - - if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { - virt_addr = phys_to_virt(phys_addr); - } else { - iomem = 1; - virt_addr = ioremap(phys_addr, width); - } -#else - virt_addr = phys_to_virt(phys_addr); -#endif - if (!value) - value = &dummy; - - switch (width) { - case 8: - *(u8*) value = *(u8*) virt_addr; - break; - case 16: - *(u16*) value = *(u16*) virt_addr; - break; - case 32: - *(u32*) value = *(u32*) virt_addr; - break; - default: - BUG(); - } - -#ifdef CONFIG_ACPI_EFI - if (iomem) - iounmap(virt_addr); -#endif - - return AE_OK; -} - -acpi_status -acpi_os_write_memory( - ACPI_PHYSICAL_ADDRESS phys_addr, - acpi_integer value, - u32 width) -{ - void *virt_addr; - -#ifdef CONFIG_ACPI_EFI - int iomem = 0; - - if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { - virt_addr = phys_to_virt(phys_addr); - } else { - iomem = 1; - virt_addr = ioremap(phys_addr,width); - } -#else - virt_addr = phys_to_virt(phys_addr); -#endif - - switch (width) { - case 8: - *(u8*) virt_addr = value; - break; - case 16: - *(u16*) virt_addr = value; - break; - case 32: - *(u32*) virt_addr = value; - break; - default: - BUG(); - } - -#ifdef CONFIG_ACPI_EFI - if (iomem) - iounmap(virt_addr); -#endif - - return AE_OK; -} - -#ifdef CONFIG_ACPI_PCI - -acpi_status -acpi_os_read_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - void *value, - u32 width) -{ - int result = 0; - if (!value) - return AE_BAD_PARAMETER; - - switch (width) - { - case 8: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 1, value); - break; - case 16: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 2, value); - break; - case 32: - result = pci_config_read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 4, value); - break; - default: - BUG(); - } - - return (result ? AE_ERROR : AE_OK); -} - -acpi_status -acpi_os_write_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - acpi_integer value, - u32 width) -{ - int result = 0; - - switch (width) - { - case 8: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 1, value); - break; - case 16: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 2, value); - break; - case 32: - result = pci_config_write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, 4, value); - break; - default: - BUG(); - } - - return (result ? AE_ERROR : AE_OK); -} - -#else /*!CONFIG_ACPI_PCI*/ - -acpi_status -acpi_os_write_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - acpi_integer value, - u32 width) -{ - return (AE_SUPPORT); -} - -acpi_status -acpi_os_read_pci_configuration ( - acpi_pci_id *pci_id, - u32 reg, - void *value, - u32 width) -{ - return (AE_SUPPORT); -} - -#endif /*CONFIG_ACPI_PCI*/ - -acpi_status -acpi_os_load_module ( - char *module_name) -{ - ACPI_FUNCTION_TRACE ("os_load_module"); - - if (!module_name) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - if (0 > request_module(module_name)) { - ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to load module [%s].\n", module_name)); - return_ACPI_STATUS (AE_ERROR); - } - - return_ACPI_STATUS (AE_OK); -} - -acpi_status -acpi_os_unload_module ( - char *module_name) -{ - if (!module_name) - return AE_BAD_PARAMETER; - - /* TODO: How on Linux? */ - /* this is done automatically for all modules with - use_count = 0, I think. see: MOD_INC_USE_COUNT -ASG */ - - return AE_OK; -} - - -/* - * See acpi_os_queue_for_execution() - */ -static int -acpi_os_queue_exec ( - void *context) -{ - ACPI_OS_DPC *dpc = (ACPI_OS_DPC*)context; - - ACPI_FUNCTION_TRACE ("os_queue_exec"); - - daemonize(); - strcpy(current->comm, "kacpidpc"); - - if (!dpc || !dpc->function) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Executing function [%p(%p)].\n", dpc->function, dpc->context)); - - dpc->function(dpc->context); - - kfree(dpc); - - return_ACPI_STATUS (AE_OK); -} - -static void -acpi_os_schedule_exec ( - void *context) -{ - ACPI_OS_DPC *dpc = NULL; - int thread_pid = -1; - - ACPI_FUNCTION_TRACE ("os_schedule_exec"); - - dpc = (ACPI_OS_DPC*)context; - if (!dpc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context)); - - thread_pid = kernel_thread(acpi_os_queue_exec, dpc, - (CLONE_FS | CLONE_FILES | SIGCHLD)); - if (thread_pid < 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to kernel_thread() failed.\n")); - acpi_os_free(dpc); - } - return_VOID; -} - -acpi_status -acpi_os_queue_for_execution( - u32 priority, - OSD_EXECUTION_CALLBACK function, - void *context) -{ - acpi_status status = AE_OK; - ACPI_OS_DPC *dpc = NULL; - - ACPI_FUNCTION_TRACE ("os_queue_for_execution"); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); - - if (!function) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - /* - * Queue via DPC: - * -------------- - * Note that we have to use two different processes for queuing DPCs: - * Interrupt-Level: Use schedule_task; can't spawn a new thread. - * Kernel-Level: Spawn a new kernel thread, as schedule_task has - * its limitations (e.g. single-threaded model), and - * all other task queues run at interrupt-level. - */ - switch (priority) { - - case OSD_PRIORITY_GPE: - { - static struct tq_struct task; - - /* - * Allocate/initialize DPC structure. Note that this memory will be - * freed by the callee. - */ - dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC); - if (!dpc) - return_ACPI_STATUS (AE_NO_MEMORY); - - dpc->function = function; - dpc->context = context; - - memset(&task, 0, sizeof(struct tq_struct)); - - task.routine = acpi_os_schedule_exec; - task.data = (void*)dpc; - - if (schedule_task(&task) < 0) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n")); - status = AE_ERROR; - } - } - break; - - default: - /* - * Allocate/initialize DPC structure. Note that this memory will be - * freed by the callee. - */ - dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_KERNEL); - if (!dpc) - return_ACPI_STATUS (AE_NO_MEMORY); - - dpc->function = function; - dpc->context = context; - - acpi_os_schedule_exec(dpc); - break; - } - - return_ACPI_STATUS (status); -} - - -acpi_status -acpi_os_create_semaphore( - u32 max_units, - u32 initial_units, - acpi_handle *handle) -{ - struct semaphore *sem = NULL; - - ACPI_FUNCTION_TRACE ("os_create_semaphore"); - - sem = acpi_os_callocate(sizeof(struct semaphore)); - if (!sem) - return_ACPI_STATUS (AE_NO_MEMORY); - - sema_init(sem, initial_units); - - *handle = (acpi_handle*)sem; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating semaphore[%p|%d].\n", *handle, initial_units)); - - return_ACPI_STATUS (AE_OK); -} - - -/* - * TODO: A better way to delete semaphores? Linux doesn't have a - * 'delete_semaphore()' function -- may result in an invalid - * pointer dereference for non-synchronized consumers. Should - * we at least check for blocked threads and signal/cancel them? - */ - -acpi_status -acpi_os_delete_semaphore( - acpi_handle handle) -{ - struct semaphore *sem = (struct semaphore*) handle; - - ACPI_FUNCTION_TRACE ("os_delete_semaphore"); - - if (!sem) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting semaphore[%p].\n", handle)); - - acpi_os_free(sem); sem = NULL; - - return_ACPI_STATUS (AE_OK); -} - - -/* - * TODO: The kernel doesn't have a 'down_timeout' function -- had to - * improvise. The process is to sleep for one scheduler quantum - * until the semaphore becomes available. Downside is that this - * may result in starvation for timeout-based waits when there's - * lots of semaphore activity. - * - * TODO: Support for units > 1? - */ -acpi_status -acpi_os_wait_semaphore( - acpi_handle handle, - u32 units, - u32 timeout) -{ - acpi_status status = AE_OK; - struct semaphore *sem = (struct semaphore*)handle; - int ret = 0; - - ACPI_FUNCTION_TRACE ("os_wait_semaphore"); - - if (!sem || (units < 1)) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - if (units > 1) - return_ACPI_STATUS (AE_SUPPORT); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); - - switch (timeout) - { - /* - * No Wait: - * -------- - * A zero timeout value indicates that we shouldn't wait - just - * acquire the semaphore if available otherwise return AE_TIME - * (a.k.a. 'would block'). - */ - case 0: - if(down_trylock(sem)) - status = AE_TIME; - break; - - /* - * Wait Indefinitely: - * ------------------ - */ - case WAIT_FOREVER: - ret = down_interruptible(sem); - if (ret < 0) - status = AE_ERROR; - break; - - /* - * Wait w/ Timeout: - * ---------------- - */ - default: - // TODO: A better timeout algorithm? - { - int i = 0; - static const int quantum_ms = 1000/HZ; - - ret = down_trylock(sem); - for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - ret = down_trylock(sem); - } - - if (ret != 0) - status = AE_TIME; - } - break; - } - - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout)); - } - else { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); - } - - return_ACPI_STATUS (status); -} - - -/* - * TODO: Support for units > 1? - */ -acpi_status -acpi_os_signal_semaphore( - acpi_handle handle, - u32 units) -{ - struct semaphore *sem = (struct semaphore *) handle; - - ACPI_FUNCTION_TRACE ("os_signal_semaphore"); - - if (!sem || (units < 1)) - return_ACPI_STATUS (AE_BAD_PARAMETER); - - if (units > 1) - return_ACPI_STATUS (AE_SUPPORT); - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Signaling semaphore[%p|%d]\n", handle, units)); - - up(sem); - - return_ACPI_STATUS (AE_OK); -} - -u32 -acpi_os_get_line(NATIVE_CHAR *buffer) -{ - -#ifdef ENABLE_DEBUGGER - if (acpi_in_debugger) { - u32 chars; - - kdb_read(buffer, sizeof(line_buf)); - - /* remove the CR kdb includes */ - chars = strlen(buffer) - 1; - buffer[chars] = '\0'; - } -#endif - - return 0; -} - -/* - * We just have to assume we're dealing with valid memory - */ - -BOOLEAN -acpi_os_readable(void *ptr, u32 len) -{ - return 1; -} - -BOOLEAN -acpi_os_writable(void *ptr, u32 len) -{ - return 1; -} - -u32 -acpi_os_get_thread_id (void) -{ - if (!in_interrupt()) - return current->pid; - - return 0; -} - -acpi_status -acpi_os_signal ( - u32 function, - void *info) -{ - switch (function) - { - case ACPI_SIGNAL_FATAL: - printk(KERN_ERR PREFIX "Fatal opcode executed\n"); - break; - case ACPI_SIGNAL_BREAKPOINT: - { - char *bp_info = (char*) info; - - printk(KERN_ERR "ACPI breakpoint: %s\n", bp_info); - } - default: - break; - } - - return AE_OK; -} - -acpi_status -acpi_os_breakpoint(NATIVE_CHAR *msg) -{ - acpi_os_printf("breakpoint: %s", msg); - - return AE_OK; -} - diff -Nru a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c --- a/drivers/acpi/pci_bind.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,309 +0,0 @@ -/* - * pci_bind.c - ACPI PCI Device Binding ($Revision: 1 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME ("pci_bind") - -#define PREFIX "ACPI: " - - -struct acpi_pci_data { - acpi_pci_id id; - struct pci_bus *bus; - struct pci_dev *dev; -}; - - -void -acpi_pci_data_handler ( - acpi_handle handle, - u32 function, - void *context) -{ - ACPI_FUNCTION_TRACE("acpi_pci_data_handler"); - - /* TBD: Anything we need to do here? */ - - return_VOID; -} - - -/** - * acpi_os_get_pci_id - * ------------------ - * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) - * to resolve PCI information for ACPI-PCI devices defined in the namespace. - * This typically occurs when resolving PCI operation region information. - */ -acpi_status -acpi_os_get_pci_id ( - acpi_handle handle, - acpi_pci_id *id) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_device *device = NULL; - struct acpi_pci_data *data = NULL; - - ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); - - if (!id) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid ACPI Bus context for device %s\n", - acpi_device_bid(device))); - return_ACPI_STATUS(AE_NOT_EXIST); - } - - status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); - if (ACPI_FAILURE(status) || !data || !data->dev) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid ACPI-PCI context for device %s\n", - acpi_device_bid(device))); - return_ACPI_STATUS(status); - } - - *id = data->id; - - /* - id->segment = data->id.segment; - id->bus = data->id.bus; - id->device = data->id.device; - id->function = data->id.function; - */ - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device %s has PCI address %02x:%02x:%02x.%02x\n", - acpi_device_bid(device), id->segment, id->bus, - id->device, id->function)); - - return_ACPI_STATUS(AE_OK); -} - - -int -acpi_pci_bind ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_pci_data *data = NULL; - struct acpi_pci_data *pdata = NULL; - char pathname[PATHNAME_MAX] = {0}; - acpi_buffer buffer = {PATHNAME_MAX, pathname}; - acpi_handle handle = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_bind"); - - if (!device || !device->parent) - return_VALUE(-EINVAL); - - data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); - if (!data) - return_VALUE(-ENOMEM); - memset(data, 0, sizeof(struct acpi_pci_data)); - - acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", - pathname)); - - /* - * Segment & Bus - * ------------- - * These are obtained via the parent device's ACPI-PCI context. - */ - status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, - (void**) &pdata); - if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid ACPI-PCI context for parent device %s\n", - acpi_device_bid(device->parent))); - result = -ENODEV; - goto end; - } - data->id.segment = pdata->id.segment; - data->id.bus = pdata->bus->number; - - /* - * Device & Function - * ----------------- - * These are simply obtained from the device's _ADR method. Note - * that a value of zero is valid. - */ - data->id.device = device->pnp.bus_address >> 16; - data->id.function = device->pnp.bus_address & 0xFFFF; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n", - data->id.segment, data->id.bus, data->id.device, - data->id.function)); - - /* - * TBD: Support slot devices (e.g. function=0xFFFF). - */ - - /* - * Locate PCI Device - * ----------------- - * Locate matching device in PCI namespace. If it doesn't exist - * this typically means that the device isn't currently inserted - * (e.g. docking station, port replicator, etc.). - */ - data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); - if (!data->dev) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", - data->id.segment, data->id.bus, - data->id.device, data->id.function)); - result = -ENODEV; - goto end; - } - if (!data->dev->bus) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n", - data->id.segment, data->id.bus, - data->id.device, data->id.function)); - result = -ENODEV; - goto end; - } - - /* - * PCI Bridge? - * ----------- - * If so, set the 'bus' field and install the 'bind' function to - * facilitate callbacks for all of its children. - */ - if (data->dev->subordinate) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device %02x:%02x:%02x.%02x is a PCI bridge\n", - data->id.segment, data->id.bus, - data->id.device, data->id.function)); - data->bus = data->dev->subordinate; - device->ops.bind = acpi_pci_bind; - } - - /* - * Attach ACPI-PCI Context - * ----------------------- - * Thus binding the ACPI and PCI devices. - */ - status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to attach ACPI-PCI context to device %s\n", - acpi_device_bid(device))); - result = -ENODEV; - goto end; - } - - /* - * PCI Routing Table - * ----------------- - * Evaluate and parse _PRT, if exists. This code is independent of - * PCI bridges (above) to allow parsing of _PRT objects within the - * scope of non-bridge devices. Note that _PRTs within the scope of - * a PCI bridge assume the bridge's subordinate bus number. - * - * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? - */ - status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); - if (ACPI_SUCCESS(status)) { - if (data->bus) /* PCI-PCI bridge */ - acpi_pci_irq_add_prt(device->handle, data->id.segment, - data->bus->number); - else /* non-bridge PCI device */ - acpi_pci_irq_add_prt(device->handle, data->id.segment, - data->id.bus); - } - -end: - if (0 != result) - kfree(data); - - return_VALUE(result); -} - - -int -acpi_pci_bind_root ( - struct acpi_device *device, - acpi_pci_id *id, - struct pci_bus *bus) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_pci_data *data = NULL; - char pathname[PATHNAME_MAX] = {0}; - acpi_buffer buffer = {PATHNAME_MAX, pathname}; - - ACPI_FUNCTION_TRACE("acpi_pci_bind_root"); - - if (!device || !id || !bus) - return_VALUE(-EINVAL); - - data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); - if (!data) - return_VALUE(-ENOMEM); - memset(data, 0, sizeof(struct acpi_pci_data)); - - data->id = *id; - data->bus = bus; - device->ops.bind = acpi_pci_bind; - - acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " - "%02x:%02x\n", pathname, id->segment, id->bus)); - - status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to attach ACPI-PCI context to device %s\n", - pathname)); - result = -ENODEV; - goto end; - } - -end: - if (result != 0) - kfree(data); - - return_VALUE(result); -} diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c --- a/drivers/acpi/pci_irq.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,391 +0,0 @@ -/* - * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 8 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2002 Dominik Brodowski - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME ("pci_irq") - -#define PREFIX "PCI: " - -struct acpi_prt_list acpi_prt; - -#ifdef CONFIG_X86 -extern void eisa_set_level_irq(unsigned int irq); -#endif - - -/* -------------------------------------------------------------------------- - PCI IRQ Routing Table (PRT) Support - -------------------------------------------------------------------------- */ - -static struct acpi_prt_entry * -acpi_pci_irq_find_prt_entry ( - int segment, - int bus, - int device, - int pin) -{ - struct list_head *node = NULL; - struct acpi_prt_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry"); - - /* - * Parse through all PRT entries looking for a match on the specified - * PCI device's segment, bus, device, and pin (don't care about func). - * - * TBD: Acquire/release lock - */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); - if ((segment == entry->id.segment) - && (bus == entry->id.bus) - && (device == entry->id.device) - && (pin == entry->pin)) { - return_PTR(entry); - } - } - - return_PTR(NULL); -} - - -static int -acpi_pci_irq_add_entry ( - acpi_handle handle, - int segment, - int bus, - acpi_pci_routing_table *prt) -{ - struct acpi_prt_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry"); - - if (!prt) - return_VALUE(-EINVAL); - - entry = kmalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); - if (!entry) - return_VALUE(-ENOMEM); - memset(entry, 0, sizeof(struct acpi_prt_entry)); - - entry->id.segment = segment; - entry->id.bus = bus; - entry->id.device = (prt->address >> 16) & 0xFFFF; - entry->id.function = prt->address & 0xFFFF; - entry->pin = prt->pin; - - /* - * Type 1: Dynamic - * --------------- - * The 'source' field specifies the PCI interrupt link device used to - * configure the IRQ assigned to this slot|dev|pin. The 'source_index' - * indicates which resource descriptor in the resource template (of - * the link device) this interrupt is allocated from. - * - * NOTE: Don't query the Link Device for IRQ information at this time - * because Link Device enumeration may not have occurred yet - * (e.g. exists somewhere 'below' this _PRT entry in the ACPI - * namespace). - */ - if (prt->source[0]) { - acpi_get_handle(handle, prt->source, &entry->link.handle); - entry->link.index = prt->source_index; - } - /* - * Type 2: Static - * -------------- - * The 'source' field is NULL, and the 'source_index' field specifies - * the IRQ value, which is hardwired to specific interrupt inputs on - * the interrupt controller. - */ - else - entry->link.index = prt->source_index; - - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, - " %02X:%02X:%02X[%c] -> %s[%d]\n", - entry->id.segment, entry->id.bus, entry->id.device, - ('A' + entry->pin), prt->source, entry->link.index)); - - /* TBD: Acquire/release lock */ - list_add_tail(&entry->node, &acpi_prt.entries); - acpi_prt.count++; - - return_VALUE(0); -} - - -int -acpi_pci_irq_add_prt ( - acpi_handle handle, - int segment, - int bus) -{ - acpi_status status = AE_OK; - char pathname[PATHNAME_MAX] = {0}; - acpi_buffer buffer = {0, NULL}; - acpi_pci_routing_table *prt = NULL; - acpi_pci_routing_table *entry = NULL; - static int first_time = 1; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt"); - - if (first_time) { - acpi_prt.count = 0; - INIT_LIST_HEAD(&acpi_prt.entries); - first_time = 0; - } - - /* - * NOTE: We're given a 'handle' to the _PRT object's parent device - * (either a PCI root bridge or PCI-PCI bridge). - */ - - buffer.length = sizeof(pathname); - buffer.pointer = pathname; - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - - printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", - pathname); - - /* - * Evaluate this _PRT and add its entries to our global list (acpi_prt). - */ - - buffer.length = 0; - buffer.pointer = NULL; - status = acpi_get_irq_routing_table(handle, &buffer); - if (status != AE_BUFFER_OVERFLOW) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", - acpi_format_exception(status))); - return_VALUE(-ENODEV); - } - - prt = kmalloc(buffer.length, GFP_KERNEL); - if (!prt) - return_VALUE(-ENOMEM); - memset(prt, 0, buffer.length); - buffer.pointer = prt; - - status = acpi_get_irq_routing_table(handle, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", - acpi_format_exception(status))); - kfree(buffer.pointer); - return_VALUE(-ENODEV); - } - - entry = prt; - - while (entry && (entry->length > 0)) { - acpi_pci_irq_add_entry(handle, segment, bus, entry); - entry = (acpi_pci_routing_table *) - ((unsigned long) entry + entry->length); - } - - kfree(prt); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - PCI Interrupt Routing Support - -------------------------------------------------------------------------- */ - -static int -acpi_pci_irq_lookup ( - int segment, - int bus, - int device, - int pin) -{ - struct acpi_prt_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Searching for PRT entry for %02x:%02x:%02x[%c]\n", - segment, bus, device, ('A' + pin))); - - entry = acpi_pci_irq_find_prt_entry(segment, bus, device, pin); - if (!entry) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); - return_VALUE(0); - } - - if (!entry->irq && entry->link.handle) - entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index); - else if (!entry->irq) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n")); - return_VALUE(0); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq)); - - return_VALUE(entry->irq); -} - - -static int -acpi_pci_irq_derive ( - struct pci_dev *dev, - int pin) -{ - struct pci_dev *bridge = dev; - int irq = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); - - if (!dev) - return_VALUE(-EINVAL); - - /* - * Attempt to derive an IRQ for this device from a parent bridge's - * PCI interrupt routing entry (a.k.a. the "bridge swizzle"). - */ - while (!irq && (bridge = bridge->bus->self)) { - pin = (pin + PCI_SLOT(bridge->devfn)) % 4; - irq = acpi_pci_irq_lookup(0, bridge->bus->number, PCI_SLOT(bridge->devfn), pin); - } - - if (!irq) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", dev->slot_name)); - return_VALUE(0); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived IRQ %d\n", irq)); - - return_VALUE(irq); -} - - -int -acpi_pci_irq_enable ( - struct pci_dev *dev) -{ - int irq = 0; - u8 pin = 0; - static u16 irq_mask = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); - - if (!dev) - return_VALUE(-EINVAL); - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - if (!pin) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", dev->slot_name)); - return_VALUE(0); - } - pin--; - - if (!dev->bus) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) 'bus' field\n")); - return_VALUE(-ENODEV); - } - - /* - * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT - * values override any BIOS-assinged IRQs set during boot. - */ - irq = acpi_pci_irq_lookup(0, dev->bus->number, PCI_SLOT(dev->devfn), pin); - if (irq) - dev->irq = irq; - - /* - * If no PRT entry was found and the device wasn't assigned an IRQ - * during boot we'll try to derive an IRQ from the device's parent - * bridge. - */ - if (!dev->irq && dev->bus->self) { - irq = acpi_pci_irq_derive(dev, pin); - if (irq) - dev->irq = irq; - } - - - if (!dev->irq) { - printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s\n", ('A' + pin), dev->slot_name); - return_VALUE(0); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", dev->slot_name, dev->irq)); - - /* - * Make sure all (legacy) PCI IRQs are set as level-triggered. - */ -#ifdef CONFIG_X86 - if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq)); - irq_mask |= (1 << dev->irq); - eisa_set_level_irq(dev->irq); - } -#endif - - return_VALUE(dev->irq); -} - - -int __init -acpi_pci_irq_init (void) -{ - struct pci_dev *dev = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_irq_init"); - - if (!acpi_prt.count) { - printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ " - "routing entries\n"); - return_VALUE(-ENODEV); - } - - /* Make sure all link devices have a valid IRQ. */ - acpi_pci_link_check(); - -#ifdef CONFIG_X86_IO_APIC - /* Program IOAPICs using data from PRT entries. */ - if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) - mp_parse_prt(); -#endif - - pci_for_each_dev(dev) - acpi_pci_irq_enable(dev); - - return_VALUE(acpi_prt.count); -} diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,581 +0,0 @@ -/* - * pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 31 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2002 Dominik Brodowski - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * TBD: - * 1. Support more than one IRQ resource entry per link device (index). - * 2. Implement start/stop mechanism and use ACPI Bus Driver facilities - * for IRQ management (e.g. start()->_SRS). - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME ("pci_link") - -#define PREFIX "ACPI: " - - -#define ACPI_PCI_LINK_MAX_POSSIBLE 16 - -static int acpi_pci_link_add (struct acpi_device *device); -static int acpi_pci_link_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_pci_link_driver = { - name: ACPI_PCI_LINK_DRIVER_NAME, - class: ACPI_PCI_LINK_CLASS, - ids: ACPI_PCI_LINK_HID, - ops: { - add: acpi_pci_link_add, - remove: acpi_pci_link_remove, - }, -}; - -struct acpi_pci_link_irq { - u8 active; /* Current IRQ */ - u8 possible_count; - u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; -}; - -struct acpi_pci_link { - struct list_head node; - struct acpi_device *device; - acpi_handle handle; - struct acpi_pci_link_irq irq; -}; - -static struct { - int count; - struct list_head entries; -} acpi_link; - - -/* -------------------------------------------------------------------------- - PCI Link Device Management - -------------------------------------------------------------------------- */ - -static int -acpi_pci_link_get_possible ( - struct acpi_pci_link *link) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_resource *resource = NULL; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_link_get_possible"); - - if (!link) - return_VALUE(-EINVAL); - - status = acpi_get_possible_resources(link->handle, &buffer); - if (ACPI_FAILURE(status) || !buffer.pointer) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRS\n")); - result = -ENODEV; - goto end; - } - - resource = (acpi_resource *) buffer.pointer; - - switch (resource->id) { - case ACPI_RSTYPE_IRQ: - { - acpi_resource_irq *p = &resource->data.irq; - if (!p || !p->number_of_interrupts) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Blank IRQ resource\n")); - result = -ENODEV; - goto end; - } - for (i = 0; (inumber_of_interrupts && iinterrupts[i]) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i])); - continue; - } - link->irq.possible[i] = p->interrupts[i]; - link->irq.possible_count++; - } - break; - } - case ACPI_RSTYPE_EXT_IRQ: - { - acpi_resource_ext_irq *p = &resource->data.extended_irq; - if (!p || !p->number_of_interrupts) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); - result = -ENODEV; - goto end; - } - for (i = 0; (inumber_of_interrupts && iinterrupts[i]) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ %d\n", p->interrupts[i])); - continue; - } - link->irq.possible[i] = p->interrupts[i]; - link->irq.possible_count++; - } - break; - } - default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Resource is not an IRQ entry\n")); - result = -ENODEV; - goto end; - break; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Found %d possible IRQs\n", link->irq.possible_count)); - -end: - kfree(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_pci_link_get_current ( - struct acpi_pci_link *link) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_resource *resource = NULL; - int irq = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_link_get_current"); - - if (!link || !link->handle) - return_VALUE(-EINVAL); - - link->irq.active = 0; - - /* Make sure the link is enabled (no use querying if it isn't). */ - result = acpi_bus_get_status(link->device); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); - goto end; - } - if (!link->device->status.enabled) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n")); - return_VALUE(0); - } - - /* - * Query and parse _CRS to get the current IRQ assignment. - */ - - status = acpi_get_current_resources(link->handle, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _CRS\n")); - result = -ENODEV; - goto end; - } - resource = (acpi_resource *) buffer.pointer; - - switch (resource->id) { - case ACPI_RSTYPE_IRQ: - { - acpi_resource_irq *p = &resource->data.irq; - if (!p || !p->number_of_interrupts) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); - result = -ENODEV; - goto end; - } - irq = p->interrupts[0]; - break; - } - case ACPI_RSTYPE_EXT_IRQ: - { - acpi_resource_ext_irq *p = &resource->data.extended_irq; - if (!p || !p->number_of_interrupts) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); - result = -ENODEV; - goto end; - } - irq = p->interrupts[0]; - break; - } - default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Resource isn't an IRQ\n")); - result = -ENODEV; - goto end; - } - - if (!irq) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid use of IRQ 0\n")); - result = -ENODEV; - goto end; - } - - /* - * Note that we don't validate that the current IRQ (_CRS) exists - * within the possible IRQs (_PRS): we blindly assume that whatever - * IRQ a boot-enabled Link device is set to is the correct one. - * (Required to support systems such as the Toshiba 5005-S504.) - */ - - link->irq.active = irq; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active)); - -end: - kfree(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_pci_link_set ( - struct acpi_pci_link *link, - int irq) -{ - int result = 0; - acpi_status status = AE_OK; - struct { - acpi_resource res; - acpi_resource end; - } resource; - acpi_buffer buffer = {sizeof(resource)+1, &resource}; - int i = 0; - int valid = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_link_set"); - - if (!link || !irq) - return_VALUE(-EINVAL); - - /* See if we're already at the target IRQ. */ - if (irq == link->irq.active) - return_VALUE(0); - - /* Make sure the target IRQ in the list of possible IRQs. */ - for (i=0; iirq.possible_count; i++) { - if (irq == link->irq.possible[i]) - valid = 1; - } - if (!valid) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq)); - return_VALUE(-EINVAL); - } - - memset(&resource, 0, sizeof(resource)); - - /* NOTE: PCI interrupts are always level / active_low / shared. */ - resource.res.id = ACPI_RSTYPE_IRQ; - resource.res.length = sizeof(acpi_resource); - resource.res.data.irq.edge_level = ACPI_LEVEL_SENSITIVE; - resource.res.data.irq.active_high_low = ACPI_ACTIVE_LOW; - resource.res.data.irq.shared_exclusive = ACPI_SHARED; - resource.res.data.irq.number_of_interrupts = 1; - resource.res.data.irq.interrupts[0] = irq; - resource.end.id = ACPI_RSTYPE_END_TAG; - - status = acpi_set_current_resources(link->handle, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n")); - return_VALUE(-ENODEV); - } - - /* Make sure the device is enabled. */ - result = acpi_bus_get_status(link->device); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); - return_VALUE(result); - } - if (!link->device->status.enabled) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); - return_VALUE(-ENODEV); - } - - /* Make sure the active IRQ is the one we requested. */ - result = acpi_pci_link_get_current(link); - if (0 != result) { - return_VALUE(result); - } - if (link->irq.active != irq) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Attempt to enable at IRQ %d resulted in IRQ %d\n", - irq, link->irq.active)); - link->irq.active = 0; - return_VALUE(-ENODEV); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active)); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - PCI Link IRQ Management - -------------------------------------------------------------------------- */ - -#define ACPI_MAX_IRQS 256 -#define ACPI_MAX_ISA_IRQ 16 - -/* - * IRQ penalties are used to promote PCI IRQ balancing. We set each ISA- - * possible IRQ (0-15) with a default penalty relative to its feasibility - * for PCI's use: - * - * Never use: 0, 1, 2 (timer, keyboard, and cascade) - * Avoid using: 13, 14, and 15 (FP error and IDE) - * Penalize: 3, 4, 6, 7, 12 (known ISA uses) - * - * Thus we're left with IRQs 5, 9, 10, 11, and everything above 15 (IO[S]APIC) - * as 'best bets' for PCI use. - */ - -static int acpi_irq_penalty[ACPI_MAX_IRQS] = { - 1000000, 1000000, 1000000, 10000, - 10000, 0, 10000, 10000, - 10000, 0, 0, 0, - 10000, 100000, 100000, 100000, -}; - - -int -acpi_pci_link_check (void) -{ - struct list_head *node = NULL; - struct acpi_pci_link *link = NULL; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_link_check"); - - /* - * Pass #1: Update penalties to facilitate IRQ balancing. - */ - list_for_each(node, &acpi_link.entries) { - - link = list_entry(node, struct acpi_pci_link, node); - if (!link) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); - continue; - } - - if (link->irq.active) - acpi_irq_penalty[link->irq.active] += 100; - else { - int penalty = 100 / link->irq.possible_count; - for (i=0; iirq.possible_count; i++) { - if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ) - acpi_irq_penalty[link->irq.possible[i]] += penalty; - } - } - } - - /* - * Pass #2: Enable boot-disabled Links at 'best' IRQ. - */ - list_for_each(node, &acpi_link.entries) { - int irq = 0; - int i = 0; - - link = list_entry(node, struct acpi_pci_link, node); - if (!link) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); - continue; - } - - if (link->irq.active) - continue; - - irq = link->irq.possible[0]; - - /* - * Select the best IRQ. This is done in reverse to promote - * the use of IRQs 9, 10, 11, and >15. - */ - for (i=(link->irq.possible_count-1); i>0; i--) { - if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]]) - irq = link->irq.possible[i]; - } - - /* Enable the link device at this IRQ. */ - acpi_pci_link_set(link, irq); - - acpi_irq_penalty[link->irq.active] += 100; - - printk(PREFIX "%s [%s] enabled at IRQ %d\n", - acpi_device_name(link->device), - acpi_device_bid(link->device), irq); - } - - return_VALUE(0); -} - - -int -acpi_pci_link_get_irq ( - acpi_handle handle, - int index) -{ - int result = 0; - struct acpi_device *device = NULL; - struct acpi_pci_link *link = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq"); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n")); - return_VALUE(0); - } - - link = (struct acpi_pci_link *) acpi_driver_data(device); - if (!link) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); - return_VALUE(0); - } - - /* TBD: Support multiple index (IRQ) entries per Link Device */ - if (0 != index) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid index %d\n", index)); - return_VALUE(0); - } - - if (!link->irq.active) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); - return_VALUE(0); - } - - return_VALUE(link->irq.active); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static int -acpi_pci_link_add ( - struct acpi_device *device) -{ - int result = 0; - struct acpi_pci_link *link = NULL; - int i = 0; - int found = 0; - - ACPI_FUNCTION_TRACE("acpi_pci_link_add"); - - if (!device) - return_VALUE(-EINVAL); - - link = kmalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); - if (!link) - return_VALUE(-ENOMEM); - memset(link, 0, sizeof(struct acpi_pci_link)); - - link->device = device; - link->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_PCI_LINK_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_PCI_LINK_CLASS); - acpi_driver_data(device) = link; - - result = acpi_pci_link_get_possible(link); - if (0 != result) - goto end; - - acpi_pci_link_get_current(link); - - printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), acpi_device_bid(device)); - for (i = 0; i < link->irq.possible_count; i++) { - if (link->irq.active == link->irq.possible[i]) { - printk(" *%d", link->irq.possible[i]); - found = 1; - } - else - printk(" %d", link->irq.possible[i]); - } - if (!link->irq.active) - printk(", disabled"); - else if (!found) - printk(", enabled at IRQ %d", link->irq.active); - printk(")\n"); - - /* TBD: Acquire/release lock */ - list_add_tail(&link->node, &acpi_link.entries); - acpi_link.count++; - -end: - if (0 != result) - kfree(link); - - return_VALUE(result); -} - - -static int -acpi_pci_link_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_pci_link *link = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_link_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - link = (struct acpi_pci_link *) acpi_driver_data(device); - - /* TBD: Acquire/release lock */ - list_del(&link->node); - - kfree(link); - - return_VALUE(0); -} - - -int __init -acpi_pci_link_init (void) -{ - ACPI_FUNCTION_TRACE("acpi_pci_link_init"); - - acpi_link.count = 0; - INIT_LIST_HEAD(&acpi_link.entries); - - if (0 > acpi_bus_register_driver(&acpi_pci_link_driver)) - return_VALUE(-ENODEV); - - return_VALUE(0); -} diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c --- a/drivers/acpi/pci_root.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,245 +0,0 @@ -/* - * pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 37 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_PCI_COMPONENT -ACPI_MODULE_NAME ("pci_root") - -extern struct pci_ops *pci_root_ops; - -#define PREFIX "ACPI: " - -static int acpi_pci_root_add (struct acpi_device *device); -static int acpi_pci_root_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_pci_root_driver = { - name: ACPI_PCI_ROOT_DRIVER_NAME, - class: ACPI_PCI_ROOT_CLASS, - ids: ACPI_PCI_ROOT_HID, - ops: { - add: acpi_pci_root_add, - remove: acpi_pci_root_remove, - }, -}; - -struct acpi_pci_root { - acpi_handle handle; - acpi_pci_id id; - struct pci_bus *bus; -}; - - -static int -acpi_pci_root_add ( - struct acpi_device *device) -{ - int result = 0; - struct acpi_pci_root *root = NULL; - acpi_status status = AE_OK; - unsigned long value = 0; - acpi_handle handle = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_root_add"); - - if (!device) - return_VALUE(-EINVAL); - - root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); - if (!root) - return_VALUE(-ENOMEM); - memset(root, 0, sizeof(struct acpi_pci_root)); - - root->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_PCI_ROOT_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_PCI_ROOT_CLASS); - acpi_driver_data(device) = root; - - /* - * TBD: Doesn't the bus driver automatically set this? - */ - device->ops.bind = acpi_pci_bind; - - /* - * Segment - * ------- - * Obtained via _SEG, if exists, otherwise assumed to be zero (0). - */ - status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL, - &value); - switch (status) { - case AE_OK: - root->id.segment = (u16) value; - break; - case AE_NOT_FOUND: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Assuming segment 0 (no _SEG)\n")); - root->id.segment = 0; - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SEG\n")); - result = -ENODEV; - goto end; - } - - /* - * Bus - * --- - * Obtained via _BBN, if exists, otherwise assumed to be zero (0). - */ - status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL, - &value); - switch (status) { - case AE_OK: - root->id.bus = (u16) value; - break; - case AE_NOT_FOUND: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); - root->id.bus = 0; - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BBN\n")); - result = -ENODEV; - goto end; - } - - /* - * Device & Function - * ----------------- - * Obtained from _ADR (which has already been evaluated for us). - */ - root->id.device = device->pnp.bus_address >> 16; - root->id.function = device->pnp.bus_address & 0xFFFF; - - /* - * TBD: Evaluate _CRS to get root bridge resources - * TBD: Need PCI interface for enumeration/configuration of roots. - */ - - printk(KERN_INFO PREFIX "%s [%s] (%02x:%02x)\n", - acpi_device_name(device), acpi_device_bid(device), - root->id.segment, root->id.bus); - - /* - * Scan the Root Bridge - * -------------------- - * Must do this prior to any attempt to bind the root device, as the - * PCI namespace does not get created until this call is made (and - * thus the root bridge's pci_dev does not exist). - */ - root->bus = pcibios_scan_root(root->handle, root->id.segment, - root->id.bus); - if (!root->bus) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Bus %02x:%02x not present in PCI namespace\n", - root->id.segment, root->id.bus)); - result = -ENODEV; - goto end; - } - - /* - * Attach ACPI-PCI Context - * ----------------------- - * Thus binding the ACPI and PCI devices. - */ - result = acpi_pci_bind_root(device, &root->id, root->bus); - if (0 != result) - goto end; - - /* - * PCI Routing Table - * ----------------- - * Evaluate and parse _PRT, if exists. - */ - status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle); - if (ACPI_SUCCESS(status)) - result = acpi_pci_irq_add_prt(root->handle, root->id.segment, - root->id.bus); - -end: - if (0 != result) - kfree(root); - - return_VALUE(result); -} - - -static int -acpi_pci_root_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_pci_root *root = NULL; - - ACPI_FUNCTION_TRACE("acpi_pci_root_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - root = (struct acpi_pci_root *) acpi_driver_data(device); - - kfree(root); - - return_VALUE(0); -} - - -int __init -acpi_pci_root_init (void) -{ - ACPI_FUNCTION_TRACE("acpi_pci_root_init"); - - /* DEBUG: - acpi_dbg_layer = ACPI_PCI_COMPONENT; - acpi_dbg_level = 0xFFFFFFFF; - */ - - if (0 > acpi_bus_register_driver(&acpi_pci_root_driver)) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -void __exit -acpi_pci_root_exit (void) -{ - ACPI_FUNCTION_TRACE("acpi_pci_root_exit"); - - acpi_bus_unregister_driver(&acpi_pci_root_driver); - - return_VOID; -} diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c --- a/drivers/acpi/power.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,610 +0,0 @@ -/* - * acpi_power.c - ACPI Bus Power Management ($Revision: 34 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_POWER_COMPONENT -ACPI_MODULE_NAME ("acpi_power") - -#define PREFIX "ACPI: " - - -int acpi_power_add (struct acpi_device *device); -int acpi_power_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_power_driver = { - name: ACPI_POWER_DRIVER_NAME, - class: ACPI_POWER_CLASS, - ids: ACPI_POWER_HID, - ops: { - add: acpi_power_add, - remove: acpi_power_remove, - }, -}; - -struct acpi_power_resource -{ - acpi_handle handle; - acpi_bus_id name; - u32 system_level; - u32 order; - int state; - int references; -}; - -static struct list_head acpi_power_resource_list; - - -/* -------------------------------------------------------------------------- - Power Resource Management - -------------------------------------------------------------------------- */ - -static int -acpi_power_get_context ( - acpi_handle handle, - struct acpi_power_resource **resource) -{ - int result = 0; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_power_get_context"); - - if (!resource) - return_VALUE(-ENODEV); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context [%p]\n", - handle)); - return_VALUE(result); - } - - *resource = (struct acpi_power_resource *) acpi_driver_data(device); - if (!resource) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -static int -acpi_power_get_state ( - struct acpi_power_resource *resource) -{ - acpi_status status = AE_OK; - unsigned long sta = 0; - - ACPI_FUNCTION_TRACE("acpi_power_get_state"); - - if (!resource) - return_VALUE(-EINVAL); - - status = acpi_evaluate_integer(resource->handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - if (sta & 0x01) - resource->state = ACPI_POWER_RESOURCE_STATE_ON; - else - resource->state = ACPI_POWER_RESOURCE_STATE_OFF; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", - resource->name, resource->state?"on":"off")); - - return_VALUE(0); -} - - -static int -acpi_power_get_list_state ( - struct acpi_handle_list *list, - int *state) -{ - int result = 0; - struct acpi_power_resource *resource = NULL; - u32 i = 0; - - ACPI_FUNCTION_TRACE("acpi_power_get_list_state"); - - if (!list || !state) - return_VALUE(-EINVAL); - - /* The state of the list is 'on' IFF all resources are 'on'. */ - - for (i=0; icount; i++) { - result = acpi_power_get_context(list->handles[i], &resource); - if (0 != result) - return_VALUE(result); - result = acpi_power_get_state(resource); - if (0 != result) - return_VALUE(result); - - *state = resource->state; - - if (*state != ACPI_POWER_RESOURCE_STATE_ON) - break; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", - *state?"on":"off")); - - return_VALUE(result); -} - - -static int -acpi_power_on ( - acpi_handle handle) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_device *device = NULL; - struct acpi_power_resource *resource = NULL; - - ACPI_FUNCTION_TRACE("acpi_power_on"); - - result = acpi_power_get_context(handle, &resource); - if (0 != result) - return_VALUE(result); - - resource->references++; - - if ((resource->references > 1) - || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n", - resource->name)); - return_VALUE(0); - } - - status = acpi_evaluate(resource->handle, "_ON", NULL, NULL); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - result = acpi_power_get_state(resource); - if (0 != result) - return_VALUE(result); - if (resource->state != ACPI_POWER_RESOURCE_STATE_ON) - return_VALUE(-ENOEXEC); - - /* Update the power resource's _device_ power state */ - result = acpi_bus_get_device(resource->handle, &device); - if (0 != result) - return_VALUE(result); - device->power.state = ACPI_STATE_D0; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", - resource->name)); - - return_VALUE(0); -} - - -static int -acpi_power_off ( - acpi_handle handle) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_device *device = NULL; - struct acpi_power_resource *resource = NULL; - - ACPI_FUNCTION_TRACE("acpi_power_off"); - - result = acpi_power_get_context(handle, &resource); - if (0 != result) - return_VALUE(result); - - if (resource->references) - resource->references--; - - if (resource->references) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Resource [%s] is still in use, dereferencing\n", - device->pnp.bus_id)); - return_VALUE(0); - } - - if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", - device->pnp.bus_id)); - return_VALUE(0); - } - - status = acpi_evaluate(resource->handle, "_OFF", NULL, NULL); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - result = acpi_power_get_state(resource); - if (0 != result) - return_VALUE(result); - if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF) - return_VALUE(-ENOEXEC); - - /* Update the power resource's _device_ power state */ - result = acpi_bus_get_device(resource->handle, &device); - if (0 != result) - return_VALUE(result); - device->power.state = ACPI_STATE_D3; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", - resource->name)); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Device Power Management - -------------------------------------------------------------------------- */ - -int -acpi_power_get_inferred_state ( - struct acpi_device *device) -{ - int result = 0; - struct acpi_handle_list *list = NULL; - int list_state = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_power_get_inferred_state"); - - if (!device) - return_VALUE(-EINVAL); - - device->power.state = ACPI_STATE_UNKNOWN; - - /* - * We know a device's inferred power state when all the resources - * required for a given D-state are 'on'. - */ - for (i=ACPI_STATE_D0; ipower.states[i].resources; - if (list->count < 1) - continue; - - result = acpi_power_get_list_state(list, &list_state); - if (0 != result) - return_VALUE(result); - - if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { - device->power.state = i; - return_VALUE(0); - } - } - - device->power.state = ACPI_STATE_D3; - - return_VALUE(0); -} - - -int -acpi_power_transition ( - struct acpi_device *device, - int state) -{ - int result = 0; - struct acpi_handle_list *cl = NULL; /* Current Resources */ - struct acpi_handle_list *tl = NULL; /* Target Resources */ - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_power_transition"); - - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) - return_VALUE(-EINVAL); - - cl = &device->power.states[device->power.state].resources; - tl = &device->power.states[state].resources; - - device->power.state = ACPI_STATE_UNKNOWN; - - if (!cl->count && !tl->count) { - result = -ENODEV; - goto end; - } - - /* TBD: Resources must be ordered. */ - - /* - * First we reference all power resources required in the target list - * (e.g. so the device doesn't loose power while transitioning). - */ - for (i=0; icount; i++) { - result = acpi_power_on(tl->handles[i]); - if (0 != result) - goto end; - } - - device->power.state = state; - - /* - * Then we dereference all power resources used in the current list. - */ - for (i=0; icount; i++) { - result = acpi_power_off(cl->handles[i]); - if (0 != result) - goto end; - } - -end: - if (0 != result) - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Error transitioning device [%s] to D%d\n", - device->pnp.bus_id, state)); - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_power_dir = NULL; - - -static int -acpi_power_read_status ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_power_resource *resource = NULL; - char *p = page; - int len; - - ACPI_FUNCTION_TRACE("acpi_power_read_status"); - - if (!data || (off != 0)) - goto end; - - resource = (struct acpi_power_resource *) data; - - p += sprintf(p, "state: "); - switch (resource->state) { - case ACPI_POWER_RESOURCE_STATE_ON: - p += sprintf(p, "on\n"); - break; - case ACPI_POWER_RESOURCE_STATE_OFF: - p += sprintf(p, "off\n"); - break; - default: - p += sprintf(p, "unknown\n"); - break; - } - - p += sprintf(p, "system level: S%d\n", - resource->system_level); - p += sprintf(p, "order: %d\n", - resource->order); - p += sprintf(p, "reference count: %d\n", - resource->references); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_power_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_power_add_fs"); - - if (!device) - return_VALUE(-EINVAL); - - if (!acpi_power_dir) { - acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); - if (!acpi_power_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_power_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'status' [R] */ - entry = create_proc_entry(ACPI_POWER_FILE_STATUS, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_POWER_FILE_STATUS)); - else { - entry->read_proc = acpi_power_read_status; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_power_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_power_remove_fs"); - - if (!acpi_power_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_power_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -int -acpi_power_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_power_resource *resource = NULL; - acpi_object acpi_object; - acpi_buffer buffer = {sizeof(acpi_object), &acpi_object}; - - ACPI_FUNCTION_TRACE("acpi_power_add"); - - if (!device) - return_VALUE(-EINVAL); - - resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); - if (!resource) - return_VALUE(-ENOMEM); - memset(resource, 0, sizeof(struct acpi_power_resource)); - - resource->handle = device->handle; - sprintf(resource->name, "%s", device->pnp.bus_id); - sprintf(acpi_device_name(device), "%s", ACPI_POWER_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_POWER_CLASS); - acpi_driver_data(device) = resource; - - /* Evalute the object to get the system level and resource order. */ - status = acpi_evaluate_object(resource->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } - resource->system_level = acpi_object.power_resource.system_level; - resource->order = acpi_object.power_resource.resource_order; - - result = acpi_power_get_state(resource); - if (0 != result) - goto end; - - switch (resource->state) { - case ACPI_POWER_RESOURCE_STATE_ON: - device->power.state = ACPI_STATE_D0; - break; - case ACPI_POWER_RESOURCE_STATE_OFF: - device->power.state = ACPI_STATE_D3; - break; - default: - device->power.state = ACPI_STATE_UNKNOWN; - break; - } - - result = acpi_power_add_fs(device); - if (0 != result) - goto end; - - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), - acpi_device_bid(device), resource->state?"on":"off"); - -end: - if (0 != result) - kfree(resource); - - return_VALUE(result); -} - - -int -acpi_power_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_power_resource *resource = NULL; - - ACPI_FUNCTION_TRACE("acpi_power_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - resource = (struct acpi_power_resource *) acpi_driver_data(device); - - acpi_power_remove_fs(device); - - kfree(resource); - - return_VALUE(0); -} - - -int __init -acpi_power_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_power_init"); - - INIT_LIST_HEAD(&acpi_power_resource_list); - - result = acpi_bus_register_driver(&acpi_power_driver); - if (0 > result) { - remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); - return_VALUE(-ENODEV); - } - - return_VALUE(0); -} - - -void __exit -acpi_power_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_power_exit"); - - /* TBD: Empty acpi_power_resource_list */ - - result = acpi_bus_unregister_driver(&acpi_power_driver); - if (0 == result) - remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); - - return_VOID; -} diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2324 +0,0 @@ -/* - * acpi_processor.c - ACPI Processor Driver ($Revision: 62 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * TBD: - * 1. Make # power/performance states dynamic. - * 2. Support duty_cycle values that span bit 4. - * 3. Optimize by having scheduler determine business instead of - * having us try to calculate it here. - * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. - * 5. Convert time values to ticks (initially) to avoid having to do - * the math (acpi_get_timer_duration). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME ("acpi_processor") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -#define PREFIX "ACPI: " - -#define US_TO_PM_TIMER_TICKS(t) ((t * PM_TIMER_FREQUENCY) / 1000000) -#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ -#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ - -#define ACPI_PROCESSOR_BUSY_METRIC 10 - -#define ACPI_PROCESSOR_MAX_POWER ACPI_C_STATE_COUNT -#define ACPI_PROCESSOR_MAX_C2_LATENCY 100 -#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000 - -#define ACPI_PROCESSOR_MAX_PERFORMANCE 8 - -#define ACPI_PROCESSOR_MAX_THROTTLING 16 -#define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */ -#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4 - -const u32 POWER_OF_2[] = {1,2,4,8,16,32,64}; - -#define ACPI_PROCESSOR_LIMIT_USER 0 -#define ACPI_PROCESSOR_LIMIT_THERMAL 1 - -static int acpi_processor_add (struct acpi_device *device); -static int acpi_processor_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_processor_driver = { - name: ACPI_PROCESSOR_DRIVER_NAME, - class: ACPI_PROCESSOR_CLASS, - ids: ACPI_PROCESSOR_HID, - ops: { - add: acpi_processor_add, - remove: acpi_processor_remove, - }, -}; - -/* Power Management */ - -struct acpi_processor_cx_policy { - u32 count; - int state; - struct { - u32 time; - u32 ticks; - u32 count; - u32 bm; - } threshold; -}; - -struct acpi_processor_cx { - u8 valid; - u32 address; - u32 latency; - u32 latency_ticks; - u32 power; - u32 usage; - struct acpi_processor_cx_policy promotion; - struct acpi_processor_cx_policy demotion; -}; - -struct acpi_processor_power { - int state; - int default_state; - u32 bm_activity; - struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; -}; - -/* Performance Management */ - -struct acpi_pct_register { - u8 descriptor; - u16 length; - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 reserved; - u64 address; -} __attribute__ ((packed)); - -struct acpi_processor_px { - acpi_integer core_frequency; /* megahertz */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer bus_master_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ -}; - -struct acpi_processor_performance { - int state; - int platform_limit; - u16 control_register; - u16 status_register; - int state_count; - struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; -}; - - -/* Throttling Control */ - -struct acpi_processor_tx { - u16 power; - u16 performance; -}; - -struct acpi_processor_throttling { - int state; - u32 address; - u8 duty_offset; - u8 duty_width; - int state_count; - struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; -}; - -/* Limit Interface */ - -struct acpi_processor_lx { - int px; /* performace state */ - int tx; /* throttle level */ -}; - -struct acpi_processor_limit { - struct acpi_processor_lx state; /* current limit */ - struct acpi_processor_lx thermal; /* thermal limit */ - struct acpi_processor_lx user; /* user limit */ -}; - - -struct acpi_processor_flags { - u8 power:1; - u8 performance:1; - u8 throttling:1; - u8 limit:1; - u8 bm_control:1; - u8 bm_check:1; - u8 reserved:2; -}; - -struct acpi_processor { - acpi_handle handle; - u32 acpi_id; - u32 id; - struct acpi_processor_flags flags; - struct acpi_processor_power power; - struct acpi_processor_performance performance; - struct acpi_processor_throttling throttling; - struct acpi_processor_limit limit; -}; - -struct acpi_processor_errata { - u8 smp; - struct { - u8 throttle:1; - u8 fdma:1; - u8 reserved:6; - u32 bmisx; - } piix4; -}; - -static struct acpi_processor *processors[NR_CPUS]; -static struct acpi_processor_errata errata; -static void (*pm_idle_save)(void) = NULL; - - -/* -------------------------------------------------------------------------- - Errata Handling - -------------------------------------------------------------------------- */ - -int -acpi_processor_errata_piix4 ( - struct pci_dev *dev) -{ - u8 rev = 0; - u8 value1 = 0; - u8 value2 = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_errata_piix4"); - - if (!dev) - return_VALUE(-EINVAL); - - /* - * Note that 'dev' references the PIIX4 ACPI Controller. - */ - - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - - switch (rev) { - case 0: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); - break; - case 1: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); - break; - case 2: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); - break; - case 3: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); - break; - } - - switch (rev) { - - case 0: /* PIIX4 A-step */ - case 1: /* PIIX4 B-step */ - /* - * See specification changes #13 ("Manual Throttle Duty Cycle") - * and #14 ("Enabling and Disabling Manual Throttle"), plus - * erratum #5 ("STPCLK# Deassertion Time") from the January - * 2002 PIIX4 specification update. Applies to only older - * PIIX4 models. - */ - errata.piix4.throttle = 1; - - case 2: /* PIIX4E */ - case 3: /* PIIX4M */ - /* - * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA - * Livelock") from the January 2002 PIIX4 specification update. - * Applies to all PIIX4 models. - */ - - /* - * BM-IDE - * ------ - * Find the PIIX4 IDE Controller and get the Bus Master IDE - * Status register address. We'll use this later to read - * each IDE controller's DMA status to make sure we catch all - * DMA activity. - */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB, - PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) - errata.piix4.bmisx = pci_resource_start(dev, 4); - - /* - * Type-F DMA - * ---------- - * Find the PIIX4 ISA Controller and read the Motherboard - * DMA controller's status to see if Type-F (Fast) DMA mode - * is enabled (bit 7) on either channel. Note that we'll - * disable C3 support if this is enabled, as some legacy - * devices won't operate well if fast DMA is disabled. - */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_0, - PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) { - pci_read_config_byte(dev, 0x76, &value1); - pci_read_config_byte(dev, 0x77, &value2); - if ((value1 & 0x80) || (value2 & 0x80)) - errata.piix4.fdma = 1; - } - - break; - } - - if (errata.piix4.bmisx) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Bus master activity detection (BM-IDE) erratum enabled\n")); - if (errata.piix4.fdma) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Type-F DMA livelock erratum (C3 disabled)\n")); - - return_VALUE(0); -} - - -int -acpi_processor_errata ( - struct acpi_processor *pr) -{ - int result = 0; - struct pci_dev *dev = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_errata"); - - if (!pr) - return_VALUE(-EINVAL); - - /* - * PIIX4 - */ - dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) - result = acpi_processor_errata_piix4(dev); - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - Power Management - -------------------------------------------------------------------------- */ - -static inline u32 -ticks_elapsed ( - u32 t1, - u32 t2) -{ - if (t2 >= t1) - return (t2 - t1); - else if (!acpi_fadt.tmr_val_ext) - return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); - else - return ((0xFFFFFFFF - t1) + t2); -} - - -static void -acpi_processor_power_activate ( - struct acpi_processor *pr, - int state) -{ - if (!pr) - return; - - pr->power.states[pr->power.state].promotion.count = 0; - pr->power.states[pr->power.state].demotion.count = 0; - - /* Cleanup from old state. */ - switch (pr->power.state) { - case ACPI_STATE_C3: - /* Disable bus master reload */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK); - break; - } - - /* Prepare to use new state. */ - switch (state) { - case ACPI_STATE_C3: - /* Enable bus master reload */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK); - break; - } - - pr->power.state = state; - - return; -} - - -static void -acpi_processor_idle (void) -{ - struct acpi_processor *pr = NULL; - struct acpi_processor_cx *cx = NULL; - int next_state = 0; - int sleep_ticks = 0; - u32 t1, t2 = 0; - - pr = processors[smp_processor_id()]; - if (!pr) - return; - - /* - * Interrupts must be disabled during bus mastering calculations and - * for C2/C3 transitions. - */ - __cli(); - - cx = &(pr->power.states[pr->power.state]); - - /* - * Check BM Activity - * ----------------- - * Check for bus mastering activity (if required), record, and check - * for demotion. - */ - if (pr->flags.bm_check) { - u32 bm_status = 0; - - pr->power.bm_activity <<= 1; - - acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, - &bm_status, ACPI_MTX_DO_NOT_LOCK); - if (bm_status) { - pr->power.bm_activity++; - acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, - 1, ACPI_MTX_DO_NOT_LOCK); - } - /* - * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect - * the true state of bus mastering activity; forcing us to - * manually check the BMIDEA bit of each IDE channel. - */ - else if (errata.piix4.bmisx) { - if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) - || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) - pr->power.bm_activity++; - } - /* - * Apply bus mastering demotion policy. Automatically demote - * to avoid a faulty transition. Note that the processor - * won't enter a low-power state during this call (to this - * funciton) but should upon the next. - * - * TBD: A better policy might be to fallback to the demotion - * state (use it for this quantum only) istead of - * demoting -- and rely on duration as our sole demotion - * qualification. This may, however, introduce DMA - * issues (e.g. floppy DMA transfer overrun/underrun). - */ - if (pr->power.bm_activity & cx->demotion.threshold.bm) { - __sti(); - next_state = cx->demotion.state; - goto end; - } - } - - cx->usage++; - - /* - * Sleep: - * ------ - * Invoke the current Cx state to put the processor to sleep. - */ - switch (pr->power.state) { - - case ACPI_STATE_C1: - /* Invoke C1. */ - safe_halt(); - /* - * TBD: Can't get time duration while in C1, as resumes - * go to an ISR rather than here. Need to instrument - * base interrupt handler. - */ - sleep_ticks = 0xFFFFFFFF; - break; - - case ACPI_STATE_C2: - /* Get start time (ticks) */ - t1 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Invoke C2 */ - inb(pr->power.states[ACPI_STATE_C2].address); - /* Dummy op - must do something useless after P_LVL2 read */ - t2 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Get end time (ticks) */ - t2 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Re-enable interrupts */ - __sti(); - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; - break; - - case ACPI_STATE_C3: - /* Disable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); - /* Get start time (ticks) */ - t1 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Invoke C3 */ - inb(pr->power.states[ACPI_STATE_C3].address); - /* Dummy op - must do something useless after P_LVL3 read */ - t2 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Get end time (ticks) */ - t2 = inl(acpi_fadt.Xpm_tmr_blk.address); - /* Enable bus master arbitration */ - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK); - /* Re-enable interrupts */ - __sti(); - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; - break; - - default: - __sti(); - return; - } - - next_state = pr->power.state; - - /* - * Promotion? - * ---------- - * Track the number of longs (time asleep is greater than threshold) - * and promote when the count threshold is reached. Note that bus - * mastering activity may prevent promotions. - */ - if (cx->promotion.state) { - if (sleep_ticks > cx->promotion.threshold.ticks) { - cx->promotion.count++; - cx->demotion.count = 0; - if (cx->promotion.count >= cx->promotion.threshold.count) { - if (pr->flags.bm_check) { - if (!(pr->power.bm_activity & cx->promotion.threshold.bm)) { - next_state = cx->promotion.state; - goto end; - } - } - else { - next_state = cx->promotion.state; - goto end; - } - } - } - } - - /* - * Demotion? - * --------- - * Track the number of shorts (time asleep is less than time threshold) - * and demote when the usage threshold is reached. - */ - if (cx->demotion.state) { - if (sleep_ticks < cx->demotion.threshold.ticks) { - cx->demotion.count++; - cx->promotion.count = 0; - if (cx->demotion.count >= cx->demotion.threshold.count) { - next_state = cx->demotion.state; - goto end; - } - } - } - -end: - /* - * New Cx State? - * ------------- - * If we're going to start using a new Cx state we must clean up - * from the previous and prepare to use the new. - */ - if (next_state != pr->power.state) - acpi_processor_power_activate(pr, next_state); - - return; -} - - -static int -acpi_processor_set_power_policy ( - struct acpi_processor *pr) -{ - ACPI_FUNCTION_TRACE("acpi_processor_set_power_policy"); - - /* - * This function sets the default Cx state policy (OS idle handler). - * Our scheme is to promote quickly to C2 but more conservatively - * to C3. We're favoring C2 for its characteristics of low latency - * (quick response), good power savings, and ability to allow bus - * mastering activity. Note that the Cx state policy is completely - * customizable and can be altered dynamically. - */ - - if (!pr) - return_VALUE(-EINVAL); - - /* - * C0/C1 - * ----- - */ - pr->power.state = ACPI_STATE_C1; - pr->power.default_state = ACPI_STATE_C1; - - /* - * C1/C2 - * ----- - * Set the default C1 promotion and C2 demotion policies, where we - * promote from C1 to C2 after several (10) successive C1 transitions, - * as we cannot (currently) measure the time spent in C1. Demote from - * C2 to C1 anytime we experience a 'short' (time spent in C2 is less - * than the C2 transtion latency). Note the simplifying assumption - * that the 'cost' of a transition is amortized when we sleep for at - * least as long as the transition's latency (thus the total transition - * time is two times the latency). - * - * TBD: Measure C1 sleep times by instrumenting the core IRQ handler. - * TBD: Demote to default C-State after long periods of activity. - * TBD: Investigate policy's use of CPU utilization -vs- sleep duration. - */ - if (pr->power.states[ACPI_STATE_C2].valid) { - pr->power.states[ACPI_STATE_C1].promotion.threshold.count = 10; - pr->power.states[ACPI_STATE_C1].promotion.threshold.ticks = - pr->power.states[ACPI_STATE_C2].latency_ticks; - pr->power.states[ACPI_STATE_C1].promotion.state = ACPI_STATE_C2; - - pr->power.states[ACPI_STATE_C2].demotion.threshold.count = 1; - pr->power.states[ACPI_STATE_C2].demotion.threshold.ticks = - pr->power.states[ACPI_STATE_C2].latency_ticks; - pr->power.states[ACPI_STATE_C2].demotion.state = ACPI_STATE_C1; - } - - /* - * C2/C3 - * ----- - * Set default C2 promotion and C3 demotion policies, where we promote - * from C2 to C3 after several (4) cycles of no bus mastering activity - * while maintaining sleep time criteria. Demote immediately on a - * short or whenever bus mastering activity occurs. - */ - if ((pr->power.states[ACPI_STATE_C2].valid) && - (pr->power.states[ACPI_STATE_C3].valid)) { - pr->power.states[ACPI_STATE_C2].promotion.threshold.count = 4; - pr->power.states[ACPI_STATE_C2].promotion.threshold.ticks = - pr->power.states[ACPI_STATE_C3].latency_ticks; - pr->power.states[ACPI_STATE_C2].promotion.threshold.bm = 0x0F; - pr->power.states[ACPI_STATE_C2].promotion.state = ACPI_STATE_C3; - - pr->power.states[ACPI_STATE_C3].demotion.threshold.count = 1; - pr->power.states[ACPI_STATE_C3].demotion.threshold.ticks = - pr->power.states[ACPI_STATE_C3].latency_ticks; - pr->power.states[ACPI_STATE_C3].demotion.threshold.bm = 0x0F; - pr->power.states[ACPI_STATE_C3].demotion.state = ACPI_STATE_C2; - } - - return_VALUE(0); -} - - -int -acpi_processor_get_power_info ( - struct acpi_processor *pr) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_power_info"); - - if (!pr) - return_VALUE(-EINVAL); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "lvl2[0x%08x] lvl3[0x%08x]\n", - pr->power.states[ACPI_STATE_C2].address, - pr->power.states[ACPI_STATE_C3].address)); - - /* TBD: Support ACPI 2.0 objects */ - - /* - * C0 - * -- - * This state exists only as filler in our array. - */ - pr->power.states[ACPI_STATE_C0].valid = 1; - - /* - * C1 - * -- - * ACPI requires C1 support for all processors. - * - * TBD: What about PROC_C1? - */ - pr->power.states[ACPI_STATE_C1].valid = 1; - - /* - * C2 - * -- - * We're (currently) only supporting C2 on UP systems. - * - * TBD: Support for C2 on MP (P_LVL2_UP). - */ - if (pr->power.states[ACPI_STATE_C2].address) { - - pr->power.states[ACPI_STATE_C2].latency = acpi_fadt.plvl2_lat; - - /* - * C2 latency must be less than or equal to 100 microseconds. - */ - if (acpi_fadt.plvl2_lat >= ACPI_PROCESSOR_MAX_C2_LATENCY) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C2 latency too large [%d]\n", - acpi_fadt.plvl2_lat)); - /* - * Only support C2 on UP systems (see TBD above). - */ - else if (errata.smp) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C2 not supported in SMP mode\n")); - /* - * Otherwise we've met all of our C2 requirements. - * Normalize the C2 latency to expidite policy. - */ - else { - pr->power.states[ACPI_STATE_C2].valid = 1; - pr->power.states[ACPI_STATE_C2].latency_ticks = - US_TO_PM_TIMER_TICKS(acpi_fadt.plvl2_lat); - } - } - - /* - * C3 - * -- - * TBD: Investigate use of WBINVD on UP/SMP system in absence of - * bm_control. - */ - if (pr->power.states[ACPI_STATE_C3].address) { - - pr->power.states[ACPI_STATE_C3].latency = acpi_fadt.plvl3_lat; - - /* - * C3 latency must be less than or equal to 1000 microseconds. - */ - if (acpi_fadt.plvl3_lat >= ACPI_PROCESSOR_MAX_C3_LATENCY) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 latency too large [%d]\n", - acpi_fadt.plvl3_lat)); - /* - * Only support C3 when bus mastering arbitration control - * is present (able to disable bus mastering to maintain - * cache coherency while in C3). - */ - else if (!pr->flags.bm_control) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 support requires bus mastering control\n")); - /* - * Only support C3 on UP systems, as bm_control is only viable - * on a UP system and flushing caches (e.g. WBINVD) is simply - * too costly (at this time). - */ - else if (errata.smp) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 not supported in SMP mode\n")); - /* - * PIIX4 Erratum #18: We don't support C3 when Type-F (fast) - * DMA transfers are used by any ISA device to avoid livelock. - * Note that we could disable Type-F DMA (as recommended by - * the erratum), but this is known to disrupt certain ISA - * devices thus we take the conservative approach. - */ - else if (errata.piix4.fdma) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 not supported on PIIX4 with Type-F DMA\n")); - } - /* - * Otherwise we've met all of our C3 requirements. - * Normalize the C2 latency to expidite policy. Enable - * checking of bus mastering status (bm_check) so we can - * use this in our C3 policy. - */ - else { - pr->power.states[ACPI_STATE_C3].valid = 1; - pr->power.states[ACPI_STATE_C3].latency_ticks = - US_TO_PM_TIMER_TICKS(acpi_fadt.plvl3_lat); - pr->flags.bm_check = 1; - } - } - - /* - * Set Default Policy - * ------------------ - * Now that we know which state are supported, set the default - * policy. Note that this policy can be changed dynamically - * (e.g. encourage deeper sleeps to conserve battery life when - * not on AC). - */ - result = acpi_processor_set_power_policy(pr); - if (0 != result) - return_VALUE(result); - - /* - * If this processor supports C2 or C3 we denote it as being 'power - * manageable'. Note that there's really no policy involved for - * when only C1 is supported. - */ - if (pr->power.states[ACPI_STATE_C2].valid - || pr->power.states[ACPI_STATE_C3].valid) - pr->flags.power = 1; - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Performance Management - -------------------------------------------------------------------------- */ - -static int -acpi_processor_get_platform_limit ( - struct acpi_processor* pr) -{ - acpi_status status = 0; - unsigned long ppc = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_platform_limit"); - - if (!pr) - return_VALUE(-EINVAL); - - /* - * _PPC indicates the maximum state currently supported by the platform - * (e.g. 0 = states 0..n; 1 = states 1..n; etc. - */ - status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); - if(ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n")); - return_VALUE(-ENODEV); - } - - pr->performance.platform_limit = (int) ppc; - - return_VALUE(0); -} - - -static int -acpi_processor_get_performance_control ( - struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = 0; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_object *pct = NULL; - acpi_object obj = {0}; - struct acpi_pct_register *reg = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control"); - - status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); - if(ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n")); - return_VALUE(-ENODEV); - } - - pct = (acpi_object *) buffer.pointer; - if (!pct || (pct->type != ACPI_TYPE_PACKAGE) - || (pct->package.count != 2)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n")); - result = -EFAULT; - goto end; - } - - /* - * control_register - */ - - obj = pct->package.elements[0]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid _PCT data (control_register)\n")); - result = -EFAULT; - goto end; - } - - reg = (struct acpi_pct_register *) (obj.buffer.pointer); - - if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space [%d] (control_register)\n", - (u32) reg->space_id)); - result = -EFAULT; - goto end; - } - - pr->performance.control_register = (u16) reg->address; - - /* - * status_register - */ - - obj = pct->package.elements[1]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid _PCT data (status_register)\n")); - result = -EFAULT; - goto end; - } - - reg = (struct acpi_pct_register *) (obj.buffer.pointer); - - if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space [%d] (status_register)\n", - (u32) reg->space_id)); - result = -EFAULT; - goto end; - } - - pr->performance.status_register = (u16) reg->address; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "control_register[0x%04x] status_register[0x%04x]\n", - pr->performance.control_register, - pr->performance.status_register)); - -end: - kfree(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_processor_get_performance_states ( - struct acpi_processor* pr) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_buffer format = {sizeof("NNNNNN"), "NNNNNN"}; - acpi_buffer state = {0, NULL}; - acpi_object *pss = NULL; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states"); - - status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); - if(ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n")); - return_VALUE(-ENODEV); - } - - pss = (acpi_object *) buffer.pointer; - if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); - result = -EFAULT; - goto end; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", - pss->package.count)); - - if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { - pr->performance.state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Limiting number of states to max (%d)\n", - ACPI_PROCESSOR_MAX_PERFORMANCE)); - } - else - pr->performance.state_count = pss->package.count; - - if (pr->performance.state_count > 1) - pr->flags.performance = 1; - - for (i = 0; i < pr->performance.state_count; i++) { - - struct acpi_processor_px *px = &(pr->performance.states[i]); - - state.length = sizeof(struct acpi_processor_px); - state.pointer = px; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); - - status = acpi_extract_package(&(pss->package.elements[i]), - &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); - result = -EFAULT; - goto end; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", - i, - (u32) px->core_frequency, - (u32) px->power, - (u32) px->transition_latency, - (u32) px->bus_master_latency, - (u32) px->control, - (u32) px->status)); - } - -end: - kfree(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_processor_set_performance ( - struct acpi_processor *pr, - int state) -{ - u16 port = 0; - u8 value = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); - - if (!pr) - return_VALUE(-EINVAL); - - if (!pr->flags.performance) - return_VALUE(-ENODEV); - - if (state >= pr->performance.state_count) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Invalid target state (P%d)\n", state)); - return_VALUE(-ENODEV); - } - - if (state < pr->performance.platform_limit) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Platform limit (P%d) overrides target state (P%d)\n", - pr->performance.platform_limit, state)); - return_VALUE(-ENODEV); - } - - if (state == pr->performance.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Already at target state (P%d)\n", state)); - return_VALUE(0); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", - pr->performance.state, state)); - - /* - * First we write the target state's 'control' value to the - * control_register. - */ - - port = pr->performance.control_register; - value = (u16) pr->performance.states[state].control; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing 0x%02x to port 0x%04x\n", value, port)); - - outb(value, port); - - /* - * Then we read the 'status_register' and compare the value with the - * target state's 'status' to make sure the transition was successful. - * Note that we'll poll for up to 1ms (100 cycles of 10us) before - * giving up. - */ - - port = pr->performance.status_register; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Looking for 0x%02x from port 0x%04x\n", - (u8) pr->performance.states[state].status, port)); - - for (i=0; i<100; i++) { - value = inb(port); - if (value == (u8) pr->performance.states[state].status) - break; - udelay(10); - } - - if (value != pr->performance.states[state].status) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); - return_VALUE(-ENODEV); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Transition successful after %d microseconds\n", - i * 10)); - - pr->performance.state = state; - - return_VALUE(0); -} - - -static int -acpi_processor_get_performance_info ( - struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_handle handle = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info"); - - if (!pr) - return_VALUE(-EINVAL); - - status = acpi_get_handle(pr->handle, "_PCT", &handle); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "ACPI-based processor performance control unavailable\n")); - return_VALUE(0); - } - - result = acpi_processor_get_performance_control(pr); - if (0 != result) - return_VALUE(result); - - result = acpi_processor_get_performance_states(pr); - if (0 != result) - return_VALUE(result); - - result = acpi_processor_get_platform_limit(pr); - if (0 != result) - return_VALUE(result); - - /* - * TBD: Don't trust the latency values we get from BIOS, but rather - * measure the latencies during run-time (e.g. get_latencies). - */ - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Throttling Control - -------------------------------------------------------------------------- */ - -static int -acpi_processor_get_throttling ( - struct acpi_processor *pr) -{ - int state = 0; - u32 value = 0; - u32 duty_mask = 0; - u32 duty_value = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_throttling"); - - if (!pr) - return_VALUE(-EINVAL); - - if (!pr->flags.throttling) - return_VALUE(-ENODEV); - - pr->throttling.state = 0; - - __cli(); - - duty_mask = pr->throttling.state_count - 1; - - duty_mask <<= pr->throttling.duty_offset; - - value = inl(pr->throttling.address); - - /* - * Compute the current throttling state when throttling is enabled - * (bit 4 is on). - */ - if (value & 0x10) { - duty_value = value & duty_mask; - duty_value >>= pr->throttling.duty_offset; - - if (duty_value) - state = pr->throttling.state_count-duty_value; - } - - pr->throttling.state = state; - - __sti(); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Throttling state is T%d (%d%% throttling applied)\n", - state, pr->throttling.states[state].performance)); - - return_VALUE(0); -} - - -static int -acpi_processor_set_throttling ( - struct acpi_processor *pr, - int state) -{ - u32 value = 0; - u32 duty_mask = 0; - u32 duty_value = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_set_throttling"); - - if (!pr) - return_VALUE(-EINVAL); - - if ((state < 0) || (state > (pr->throttling.state_count - 1))) - return_VALUE(-EINVAL); - - if (!pr->flags.throttling) - return_VALUE(-ENODEV); - - if (state == pr->throttling.state) - return_VALUE(0); - - __cli(); - - /* - * Calculate the duty_value and duty_mask. - */ - if (state) { - duty_value = pr->throttling.state_count - state; - - duty_value <<= pr->throttling.duty_offset; - - /* Used to clear all duty_value bits */ - duty_mask = pr->throttling.state_count - 1; - - duty_mask <<= acpi_fadt.duty_offset; - duty_mask = ~duty_mask; - } - - /* - * Disable throttling by writing a 0 to bit 4. Note that we must - * turn it off before you can change the duty_value. - */ - value = inl(pr->throttling.address); - if (value & 0x10) { - value &= 0xFFFFFFEF; - outl(value, pr->throttling.address); - } - - /* - * Write the new duty_value and then enable throttling. Note - * that a state value of 0 leaves throttling disabled. - */ - if (state) { - value &= duty_mask; - value |= duty_value; - outl(value, pr->throttling.address); - - value |= 0x00000010; - outl(value, pr->throttling.address); - } - - pr->throttling.state = state; - - __sti(); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Throttling state set to T%d (%d%%)\n", state, - (pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0))); - - return_VALUE(0); -} - - -static int -acpi_processor_get_throttling_info ( - struct acpi_processor *pr) -{ - int result = 0; - int step = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info"); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", - pr->throttling.address, - pr->throttling.duty_offset, - pr->throttling.duty_width)); - - if (!pr) - return_VALUE(-EINVAL); - - /* TBD: Support ACPI 2.0 objects */ - - if (!pr->throttling.address) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); - return_VALUE(0); - } - else if (!pr->throttling.duty_width) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n")); - return_VALUE(0); - } - /* TBD: Support duty_cycle values that span bit 4. */ - else if ((pr->throttling.duty_offset - + pr->throttling.duty_width) > 4) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n")); - return_VALUE(0); - } - - /* - * PIIX4 Errata: We don't support throttling on the original PIIX4. - * This shouldn't be an issue as few (if any) mobile systems ever - * used this part. - */ - if (errata.piix4.throttle) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Throttling not supported on PIIX4 A- or B-step\n")); - return_VALUE(0); - } - - pr->throttling.state_count = POWER_OF_2[acpi_fadt.duty_width]; - - /* - * Compute state values. Note that throttling displays a linear power/ - * performance relationship (at 50% performance the CPU will consume - * 50% power). Values are in 1/10th of a percent to preserve accuracy. - */ - - step = (1000 / pr->throttling.state_count); - - for (i=0; ithrottling.state_count; i++) { - pr->throttling.states[i].performance = step * i; - pr->throttling.states[i].power = step * i; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", - pr->throttling.state_count)); - - pr->flags.throttling = 1; - - /* - * Disable throttling (if enabled). We'll let subsequent policy (e.g. - * thermal) decide to lower performance if it so chooses, but for now - * we'll crank up the speed. - */ - - result = acpi_processor_get_throttling(pr); - if (0 != result) - goto end; - - if (pr->throttling.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n", - pr->throttling.state)); - result = acpi_processor_set_throttling(pr, 0); - if (0 != result) - goto end; - } - -end: - if (0 != result) - pr->flags.throttling = 0; - - return_VALUE(result); -} - - -/* -------------------------------------------------------------------------- - Limit Interface - -------------------------------------------------------------------------- */ - -static int -acpi_processor_apply_limit ( - struct acpi_processor* pr) -{ - int result = 0; - u16 px = 0; - u16 tx = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_apply_limit"); - - if (!pr) - return_VALUE(-EINVAL); - - if (!pr->flags.limit) - return_VALUE(-ENODEV); - - if (pr->flags.performance) { - px = pr->performance.platform_limit; - if (pr->limit.user.px > px) - px = pr->limit.user.px; - if (pr->limit.thermal.px > px) - px = pr->limit.thermal.px; - - result = acpi_processor_set_performance(pr, px); - if (0 != result) - goto end; - } - - if (pr->flags.throttling) { - if (pr->limit.user.tx > tx) - tx = pr->limit.user.tx; - if (pr->limit.thermal.tx > tx) - tx = pr->limit.thermal.tx; - - result = acpi_processor_set_throttling(pr, tx); - if (0 != result) - goto end; - } - - pr->limit.state.px = px; - pr->limit.state.tx = tx; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d] limit set to (P%d:T%d)\n", - pr->id, - pr->limit.state.px, - pr->limit.state.tx)); - -end: - if (0 != result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to set limit\n")); - - return_VALUE(result); -} - - -int -acpi_processor_set_thermal_limit ( - acpi_handle handle, - int type) -{ - int result = 0; - struct acpi_processor *pr = NULL; - struct acpi_device *device = NULL; - int px = 0; - int tx = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit"); - - if ((type < ACPI_PROCESSOR_LIMIT_NONE) - || (type > ACPI_PROCESSOR_LIMIT_DECREMENT)) - return_VALUE(-EINVAL); - - result = acpi_bus_get_device(handle, &device); - if (0 != result) - return_VALUE(result); - - pr = (struct acpi_processor *) acpi_driver_data(device); - if (!pr) - return_VALUE(-ENODEV); - - if (!pr->flags.limit) - return_VALUE(-ENODEV); - - /* Thermal limits are always relative to the current Px/Tx state. */ - if (pr->flags.performance) - pr->limit.thermal.px = pr->performance.state; - if (pr->flags.throttling) - pr->limit.thermal.tx = pr->throttling.state; - - /* - * Our default policy is to only use throttling at the lowest - * performance state. - */ - - switch (type) { - - case ACPI_PROCESSOR_LIMIT_NONE: - px = 0; - tx = 0; - break; - - case ACPI_PROCESSOR_LIMIT_INCREMENT: - if (pr->flags.performance) { - if (px == (pr->performance.state_count - 1)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "At maximum performance state\n")); - else { - px++; - goto end; - } - } - if (pr->flags.throttling) { - if (tx == (pr->throttling.state_count - 1)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "At maximum throttling state\n")); - else - tx++; - } - break; - - case ACPI_PROCESSOR_LIMIT_DECREMENT: - if (pr->flags.performance) { - if (px == pr->performance.platform_limit) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "At minimum performance state\n")); - else { - px--; - goto end; - } - } - if (pr->flags.throttling) { - if (tx == 0) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "At minimum throttling state\n")); - else - tx--; - } - break; - } - -end: - pr->limit.thermal.px = px; - pr->limit.thermal.tx = tx; - - result = acpi_processor_apply_limit(pr); - if (0 != result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to set thermal limit\n")); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n", - pr->limit.thermal.px, - pr->limit.thermal.tx)); - - return_VALUE(result); -} - - -static int -acpi_processor_get_limit_info ( - struct acpi_processor *pr) -{ - ACPI_FUNCTION_TRACE("acpi_processor_get_limit_info"); - - if (!pr) - return_VALUE(-EINVAL); - - if (pr->flags.performance || pr->flags.throttling) - pr->flags.limit = 1; - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_processor_dir = NULL; - -static int -acpi_processor_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_processor *pr = (struct acpi_processor *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_read_info"); - - if (!pr || (off != 0)) - goto end; - - p += sprintf(p, "processor id: %d\n", - pr->id); - - p += sprintf(p, "acpi id: %d\n", - pr->acpi_id); - - p += sprintf(p, "bus mastering control: %s\n", - pr->flags.bm_control ? "yes" : "no"); - - p += sprintf(p, "power management: %s\n", - pr->flags.power ? "yes" : "no"); - - p += sprintf(p, "throttling control: %s\n", - pr->flags.throttling ? "yes" : "no"); - - p += sprintf(p, "performance management: %s\n", - pr->flags.performance ? "yes" : "no"); - - p += sprintf(p, "limit interface: %s\n", - pr->flags.limit ? "yes" : "no"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_processor_read_power ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_processor *pr = (struct acpi_processor *) data; - char *p = page; - int len = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_read_power"); - - if (!pr || (off != 0)) - goto end; - - p += sprintf(p, "active state: C%d\n", - pr->power.state); - - p += sprintf(p, "default state: C%d\n", - pr->power.default_state); - - p += sprintf(p, "bus master activity: %08x\n", - pr->power.bm_activity); - - p += sprintf(p, "states:\n"); - - for (i=1; ipower.state?'*':' '), i); - - if (!pr->power.states[i].valid) { - p += sprintf(p, "\n"); - continue; - } - - if (pr->power.states[i].promotion.state) - p += sprintf(p, "promotion[C%d] ", - pr->power.states[i].promotion.state); - else - p += sprintf(p, "promotion[--] "); - - if (pr->power.states[i].demotion.state) - p += sprintf(p, "demotion[C%d] ", - pr->power.states[i].demotion.state); - else - p += sprintf(p, "demotion[--] "); - - p += sprintf(p, "latency[%03d] usage[%08d]\n", - pr->power.states[i].latency, - pr->power.states[i].usage); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_processor_read_performance ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_processor *pr = (struct acpi_processor *) data; - char *p = page; - int len = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_read_performance"); - - if (!pr || (off != 0)) - goto end; - - if (!pr->flags.performance) { - p += sprintf(p, "\n"); - goto end; - } - - p += sprintf(p, "state count: %d\n", - pr->performance.state_count); - - p += sprintf(p, "active state: P%d\n", - pr->performance.state); - - p += sprintf(p, "states:\n"); - - for (i=0; iperformance.state_count; i++) - p += sprintf(p, " %cP%d: %d MHz, %d mW, %d uS\n", - (i == pr->performance.state?'*':' '), i, - (u32) pr->performance.states[i].core_frequency, - (u32) pr->performance.states[i].power, - (u32) pr->performance.states[i].transition_latency); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_processor_write_performance ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_processor *pr = (struct acpi_processor *) data; - char state_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_processor_write_performance"); - - if (!pr || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - - result = acpi_processor_set_performance(pr, - simple_strtoul(state_string, NULL, 0)); - if (0 != result) - return_VALUE(result); - - return_VALUE(count); -} - - -static int -acpi_processor_read_throttling ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_processor *pr = (struct acpi_processor *) data; - char *p = page; - int len = 0; - int i = 0; - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_read_throttling"); - - if (!pr || (off != 0)) - goto end; - - if (!(pr->throttling.state_count > 0)) { - p += sprintf(p, "\n"); - goto end; - } - - result = acpi_processor_get_throttling(pr); - - if (result) { - p += sprintf(p, "Could not determine current throttling state.\n"); - goto end; - } - - p += sprintf(p, "state count: %d\n", - pr->throttling.state_count); - - p += sprintf(p, "active state: T%d\n", - pr->throttling.state); - - p += sprintf(p, "states:\n"); - - for (i=0; ithrottling.state_count; i++) - p += sprintf(p, " %cT%d: %02d%%\n", - (i == pr->throttling.state?'*':' '), i, - (pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0)); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_processor_write_throttling ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_processor *pr = (struct acpi_processor *) data; - char state_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_processor_write_throttling"); - - if (!pr || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - - result = acpi_processor_set_throttling(pr, - simple_strtoul(state_string, NULL, 0)); - if (0 != result) - return_VALUE(result); - - return_VALUE(count); -} - - -static int -acpi_processor_read_limit ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_processor *pr = (struct acpi_processor *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_read_limit"); - - if (!pr || (off != 0)) - goto end; - - if (!pr->flags.limit) { - p += sprintf(p, "\n"); - goto end; - } - - p += sprintf(p, "active limit: P%d:T%d\n", - pr->limit.state.px, pr->limit.state.tx); - - p += sprintf(p, "platform limit: P%d:T0\n", - pr->flags.performance?pr->performance.platform_limit:0); - - p += sprintf(p, "user limit: P%d:T%d\n", - pr->limit.user.px, pr->limit.user.tx); - - p += sprintf(p, "thermal limit: P%d:T%d\n", - pr->limit.thermal.px, pr->limit.thermal.tx); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_processor_write_limit ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_processor *pr = (struct acpi_processor *) data; - char limit_string[25] = {'\0'}; - int px = 0; - int tx = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_write_limit"); - - if (!pr || (count > sizeof(limit_string) - 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n")); - return_VALUE(-EINVAL); - } - - if (copy_from_user(limit_string, buffer, count)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n")); - return_VALUE(-EFAULT); - } - - limit_string[count] = '\0'; - - if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); - return_VALUE(-EINVAL); - } - - if (pr->flags.performance) { - if ((px < pr->performance.platform_limit) - || (px > (pr->performance.state_count - 1))) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid px\n")); - return_VALUE(-EINVAL); - } - pr->limit.user.px = px; - } - - if (pr->flags.throttling) { - if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid tx\n")); - return_VALUE(-EINVAL); - } - pr->limit.user.tx = tx; - } - - result = acpi_processor_apply_limit(pr); - - return_VALUE(count); -} - - -static int -acpi_processor_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_add_fs"); - - if (!acpi_processor_dir) { - acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, - acpi_root_dir); - if (!acpi_processor_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_processor_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'info' [R] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_INFO)); - else { - entry->read_proc = acpi_processor_read_info; - entry->data = acpi_driver_data(device); - } - - /* 'power' [R] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_POWER, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_POWER)); - else { - entry->read_proc = acpi_processor_read_power; - entry->data = acpi_driver_data(device); - } - - /* 'performance' [R/W] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_PERFORMANCE)); - else { - entry->read_proc = acpi_processor_read_performance; - entry->write_proc = acpi_processor_write_performance; - entry->data = acpi_driver_data(device); - } - - /* 'throttling' [R/W] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_THROTTLING)); - else { - entry->read_proc = acpi_processor_read_throttling; - entry->write_proc = acpi_processor_write_throttling; - entry->data = acpi_driver_data(device); - } - - /* 'limit' [R/W] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_LIMIT)); - else { - entry->read_proc = acpi_processor_read_limit; - entry->write_proc = acpi_processor_write_limit; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_processor_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_processor_remove_fs"); - - if (!acpi_processor_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static int -acpi_processor_get_info ( - struct acpi_processor *pr) -{ - acpi_status status = 0; - acpi_object object = {0}; - acpi_buffer buffer = {sizeof(acpi_object), &object}; - static int cpu_count = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_info"); - - if (!pr) - return_VALUE(-EINVAL); - -#ifdef CONFIG_SMP - if (smp_num_cpus > 1) - errata.smp = smp_num_cpus; -#endif - - acpi_processor_errata(pr); - - /* - * Check to see if we have bus mastering arbitration control. This - * is required for proper C3 usage (to maintain cache coherency). - */ - if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) { - pr->flags.bm_control = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Bus mastering arbitration control present\n")); - } - else - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "No bus mastering arbitration control\n")); - - /* - * Evalute the processor object. Note that it is common on SMP to - * have the first (boot) processor with a valid PBLK address while - * all others have a NULL address. - */ - status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error evaluating processor object\n")); - return_VALUE(-ENODEV); - } - - /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c - */ - pr->id = cpu_count++; - pr->acpi_id = object.processor.proc_id; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, - pr->acpi_id)); - - if (!object.processor.pblk_address) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); - else if (object.processor.pblk_length < 6) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n", - object.processor.pblk_length)); - else { - pr->throttling.address = object.processor.pblk_address; - pr->throttling.duty_offset = acpi_fadt.duty_offset; - pr->throttling.duty_width = acpi_fadt.duty_width; - pr->power.states[ACPI_STATE_C2].address = - object.processor.pblk_address + 4; - pr->power.states[ACPI_STATE_C3].address = - object.processor.pblk_address + 5; - } - - acpi_processor_get_power_info(pr); - acpi_processor_get_performance_info(pr); - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - - return_VALUE(0); -} - - -static void -acpi_processor_notify ( - acpi_handle handle, - u32 event, - void *data) -{ - int result = 0; - struct acpi_processor *pr = (struct acpi_processor *) data; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_notify"); - - if (!pr) - return_VOID; - - if (0 != acpi_bus_get_device(pr->handle, &device)) - return_VOID; - - switch (event) { - case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: - result = acpi_processor_get_platform_limit(pr); - if (0 == result) - acpi_processor_apply_limit(pr); - - acpi_bus_generate_event(device, event, - pr->performance.platform_limit); - break; - case ACPI_PROCESSOR_NOTIFY_POWER: - /* TBD */ - acpi_bus_generate_event(device, event, 0); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return_VOID; -} - - -static int -acpi_processor_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_processor *pr = NULL; - u32 i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_add"); - - if (!device) - return_VALUE(-EINVAL); - - pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL); - if (!pr) - return_VALUE(-ENOMEM); - memset(pr, 0, sizeof(struct acpi_processor)); - - pr->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_PROCESSOR_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_PROCESSOR_CLASS); - acpi_driver_data(device) = pr; - - result = acpi_processor_get_info(pr); - if (0 != result) - goto end; - - result = acpi_processor_add_fs(device); - if (0 != result) - goto end; - - status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, - acpi_processor_notify, pr); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); - result = -ENODEV; - goto end; - } - - processors[pr->id] = pr; - - /* - * Install the idle handler if processor power management is supported. - * Note that the default idle handler (default_idle) will be used on - * platforms that only support C1. - */ - if ((pr->id == 0) && (pr->flags.power)) { - pm_idle_save = pm_idle; - pm_idle = acpi_processor_idle; - } - - printk(KERN_INFO PREFIX "%s [%s] (supports", - acpi_device_name(device), acpi_device_bid(device)); - for (i=1; ipower.states[i].valid) - printk(" C%d", i); - if (pr->flags.performance) - printk(", %d performance states", pr->performance.state_count); - if (pr->flags.throttling) - printk(", %d throttling states", pr->throttling.state_count); - printk(")\n"); - -end: - if (0 != result) { - acpi_processor_remove_fs(device); - kfree(pr); - } - - return_VALUE(result); -} - - -static int -acpi_processor_remove ( - struct acpi_device *device, - int type) -{ - acpi_status status = AE_OK; - struct acpi_processor *pr = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - pr = (struct acpi_processor *) acpi_driver_data(device); - - /* Unregister the idle handler when processor #0 is removed. */ - if (pr->id == 0) - pm_idle = pm_idle_save; - - status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, - acpi_processor_notify); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - return_VALUE(-ENODEV); - } - - acpi_processor_remove_fs(device); - - processors[pr->id] = NULL; - - kfree(pr); - - return_VALUE(0); -} - - -static int __init -acpi_processor_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_init"); - - memset(&processors, 0, sizeof(processors)); - memset(&errata, 0, sizeof(errata)); - - result = acpi_bus_register_driver(&acpi_processor_driver); - if (0 > result) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -static void __exit -acpi_processor_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_exit"); - - result = acpi_bus_unregister_driver(&acpi_processor_driver); - if (0 == result) - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); - - return_VOID; -} - - -module_init(acpi_processor_init); -module_exit(acpi_processor_exit); diff -Nru a/drivers/acpi/system.c b/drivers/acpi/system.c --- a/drivers/acpi/system.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1282 +0,0 @@ -/* - * acpi_system.c - ACPI System Driver ($Revision: 50 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __i386__ -#include -#endif -#include "acpi_bus.h" -#include "acpi_drivers.h" - -#ifdef CONFIG_X86 -#ifdef CONFIG_ACPI_SLEEP -#include -#endif -#endif - - -#define _COMPONENT ACPI_SYSTEM_COMPONENT -ACPI_MODULE_NAME ("acpi_system") - -#define PREFIX "ACPI: " - -extern FADT_DESCRIPTOR acpi_fadt; - -static int acpi_system_add (struct acpi_device *device); -static int acpi_system_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_system_driver = { - name: ACPI_SYSTEM_DRIVER_NAME, - class: ACPI_SYSTEM_CLASS, - ids: ACPI_SYSTEM_HID, - ops: { - add: acpi_system_add, - remove: acpi_system_remove - }, -}; - -struct acpi_system -{ - acpi_handle handle; - u8 states[ACPI_S_STATE_COUNT]; -}; - -/* Global vars for handling event proc entry */ -static spinlock_t acpi_system_event_lock = SPIN_LOCK_UNLOCKED; -int event_is_open = 0; -extern struct list_head acpi_bus_event_list; -extern wait_queue_head_t acpi_bus_event_queue; - -/* -------------------------------------------------------------------------- - System Sleep - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_PM - -static void -acpi_power_off (void) -{ - acpi_enter_sleep_state_prep(ACPI_STATE_S5); - ACPI_DISABLE_IRQS(); - acpi_enter_sleep_state(ACPI_STATE_S5); -} - -#endif /*CONFIG_PM*/ - - -#ifdef CONFIG_ACPI_SLEEP - -/** - * acpi_system_restore_state - OS-specific restoration of state - * @state: sleep state we're exiting - * - * Note that if we're coming back from S4, the memory image should have already - * been loaded from the disk and is already in place. (Otherwise how else would we - * be here?). - */ -acpi_status -acpi_system_restore_state ( - u32 state) -{ - /* restore processor state - * We should only be here if we're coming back from STR or STD. - * And, in the case of the latter, the memory image should have already - * been loaded from disk. - */ - if (state > ACPI_STATE_S1) - acpi_restore_state_mem(); - - /* wait for power to come back */ - mdelay(10); -#ifdef HAVE_NEW_DEVICE_MODEL - /* turn all the devices back on */ - device_resume(RESUME_POWER_ON); - - /* enable interrupts once again */ - ACPI_ENABLE_IRQS(); - - /* restore device context */ - device_resume(RESUME_RESTORE_STATE); -#endif - return AE_OK; -} - -/** - * acpi_system_save_state - save OS specific state and power down devices - * @state: sleep state we're entering. - * - * This handles saving all context to memory, and possibly disk. - * First, we call to the device driver layer to save device state. - * Once we have that, we save whatevery processor and kernel state we - * need to memory. - * If we're entering S4, we then write the memory image to disk. - * - * Only then is it safe for us to power down devices, since we may need - * the disks and upstream buses to write to. - */ -acpi_status -acpi_system_save_state( - u32 state) -{ - int error = 0; - -#ifdef HAVE_NEW_DEVICE_MODEL - /* Send notification to devices that they will be suspended. - * If any device or driver cannot make the transition, either up - * or down, we'll get an error back. - */ - error = device_suspend(state, SUSPEND_NOTIFY); - if (error) - return AE_ERROR; -#endif - if (state < ACPI_STATE_S5) { - -#ifdef HAVE_NEW_DEVICE_MODEL - /* Tell devices to stop I/O and actually save their state. - * It is theoretically possible that something could fail, - * so handle that gracefully.. - */ - error = device_suspend(state, SUSPEND_SAVE_STATE); - if (error) { - /* tell devices to restore state if they have - * it saved and to start taking I/O requests. - */ - device_resume(RESUME_RESTORE_STATE); - return error; - } -#endif - - /* flush caches */ - ACPI_FLUSH_CPU_CACHE(); - - /* Do arch specific saving of state. */ - if (state > ACPI_STATE_S1) { - error = acpi_save_state_mem(); - - if (!error && (state == ACPI_STATE_S4)) - error = acpi_save_state_disk(); - -#ifdef HAVE_NEW_DEVICE_MODEL - if (error) { - device_resume(RESUME_RESTORE_STATE); - return error; - } -#endif - } - } -#ifdef HAVE_NEW_DEVICE_MODEL - /* disable interrupts - * Note that acpi_suspend -- our caller -- will do this once we return. - * But, we want it done early, so we don't get any suprises during - * the device suspend sequence. - */ - ACPI_DISABLE_IRQS(); - - /* Unconditionally turn off devices. - * Obvious if we enter a sleep state. - * If entering S5 (soft off), this should put devices in a - * quiescent state. - */ - error = device_suspend(state, SUSPEND_POWER_DOWN); - - /* We're pretty screwed if we got an error from this. - * We try to recover by simply calling our own restore_state - * function; see above for definition. - * - * If it's S5 though, go through with it anyway.. - */ - if (error && state != ACPI_STATE_S5) - acpi_system_restore_state(state); -#endif - return error ? AE_ERROR : AE_OK; -} - - -/**************************************************************************** - * - * FUNCTION: acpi_system_suspend - * - * PARAMETERS: %state: Sleep state to enter. - * - * RETURN: acpi_status, whether or not we successfully entered and - * exited sleep. - * - * DESCRIPTION: Perform OS-specific action to enter sleep state. - * This is the final step in going to sleep, per spec. If we - * know we're coming back (i.e. not entering S5), we save the - * processor flags. [ We'll have to save and restore them anyway, - * so we use the arch-agnostic save_flags and restore_flags - * here.] We then set the place to return to in arch-specific - * globals using arch_set_return_point. Finally, we call the - * ACPI function to write the proper values to I/O ports. - * - ****************************************************************************/ - -acpi_status -acpi_system_suspend( - u32 state) -{ - acpi_status status = AE_ERROR; - unsigned long flags = 0; - - save_flags(flags); - kernel_fpu_begin(); - - switch (state) - { - case ACPI_STATE_S1: - /* do nothing */ - break; - - case ACPI_STATE_S2: - case ACPI_STATE_S3: - save_register_state((unsigned long)&&acpi_sleep_done); - break; - } - - barrier(); - status = acpi_enter_sleep_state(state); - -acpi_sleep_done: - - restore_register_state(); - fix_processor_context(); - - kernel_fpu_end(); - restore_flags(flags); - - return status; -} - - -/** - * acpi_suspend - OS-agnostic system suspend/resume support (S? states) - * @state: state we're entering - * - */ -acpi_status -acpi_suspend ( - u32 state) -{ - acpi_status status; - - /* get out if state is invalid */ - if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5) - return AE_ERROR; - - /* do we have a wakeup address for S2 and S3? */ - if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) { - if (!acpi_wakeup_address) - return AE_ERROR; - acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) acpi_wakeup_address); - } - - acpi_enter_sleep_state_prep(state); - - status = acpi_system_save_state(state); - if (!ACPI_SUCCESS(status)) - return status; - - /* disable interrupts and flush caches */ - ACPI_DISABLE_IRQS(); - ACPI_FLUSH_CPU_CACHE(); - - /* perform OS-specific sleep actions */ - status = acpi_system_suspend(state); - - /* Even if we failed to go to sleep, all of the devices are in an suspended - * mode. So, we run these unconditionaly to make sure we have a usable system - * no matter what. - */ - acpi_system_restore_state(state); - acpi_leave_sleep_state(state); - - /* make sure interrupts are enabled */ - ACPI_ENABLE_IRQS(); - - /* reset firmware waking vector */ - acpi_set_firmware_waking_vector((ACPI_PHYSICAL_ADDRESS) 0); - - return status; -} - -#endif /* CONFIG_ACPI_SLEEP */ - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - - -static int -acpi_system_read_info ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_system *system = (struct acpi_system *) data; - char *p = page; - int size = 0; - u32 i = 0; - - ACPI_FUNCTION_TRACE("acpi_system_read_info"); - - if (!system || (off != 0)) - goto end; - - p += sprintf(p, "version: %x\n", ACPI_CA_VERSION); - - p += sprintf(p, "states: "); - for (i=0; istates[i]) - p += sprintf(p, "S%d ", i); - } - p += sprintf(p, "\n"); - -end: - size = (p - page); - if (size <= off+count) *eof = 1; - *start = page + off; - size -= off; - if (size>count) size = count; - if (size<0) size = 0; - - return_VALUE(size); -} - -static int acpi_system_open_event(struct inode *inode, struct file *file); -static ssize_t acpi_system_read_event (struct file*, char*, size_t, loff_t*); -static int acpi_system_close_event(struct inode *inode, struct file *file); -static unsigned int acpi_system_poll_event(struct file *file, poll_table *wait); - - -static struct file_operations acpi_system_event_ops = { - open: acpi_system_open_event, - read: acpi_system_read_event, - release: acpi_system_close_event, - poll: acpi_system_poll_event, -}; - -static int -acpi_system_open_event(struct inode *inode, struct file *file) -{ - spin_lock_irq (&acpi_system_event_lock); - - if(event_is_open) - goto out_busy; - - event_is_open = 1; - - spin_unlock_irq (&acpi_system_event_lock); - return 0; - -out_busy: - spin_unlock_irq (&acpi_system_event_lock); - return -EBUSY; -} - -static ssize_t -acpi_system_read_event ( - struct file *file, - char *buffer, - size_t count, - loff_t *ppos) -{ - int result = 0; - char outbuf[ACPI_MAX_STRING]; - int size = 0; - struct acpi_bus_event event; - - ACPI_FUNCTION_TRACE("acpi_system_read_event"); - - memset(&event, 0, sizeof(struct acpi_bus_event)); - - if (count < ACPI_MAX_STRING) - goto end; - - if ((file->f_flags & O_NONBLOCK) - && (list_empty(&acpi_bus_event_list))) - return_VALUE(-EAGAIN); - - result = acpi_bus_receive_event(&event); - if (0 != result) { - size = sprintf(outbuf, "error\n"); - goto end; - } - - size = sprintf(outbuf, "%s %s %08x %08x\n", - event.device_class?event.device_class:"", - event.bus_id?event.bus_id:"", - event.type, - event.data); - -end: - if (copy_to_user(buffer, outbuf, size)) - return_VALUE(-EFAULT); - - *ppos += size; - - return_VALUE(size); -} - -static int -acpi_system_close_event(struct inode *inode, struct file *file) -{ - spin_lock_irq (&acpi_system_event_lock); - event_is_open = 0; - spin_unlock_irq (&acpi_system_event_lock); - return 0; -} - -static unsigned int -acpi_system_poll_event( - struct file *file, - poll_table *wait) -{ - poll_wait(file, &acpi_bus_event_queue, wait); - if (!list_empty(&acpi_bus_event_list)) - return POLLIN | POLLRDNORM; - return 0; -} - -static ssize_t acpi_system_read_dsdt (struct file*, char*, size_t, loff_t*); - -static struct file_operations acpi_system_dsdt_ops = { - read: acpi_system_read_dsdt, -}; - -static ssize_t -acpi_system_read_dsdt ( - struct file *file, - char *buffer, - size_t count, - loff_t *ppos) -{ - acpi_status status = AE_OK; - acpi_buffer dsdt = {ACPI_ALLOCATE_BUFFER, NULL}; - void *data = 0; - size_t size = 0; - - ACPI_FUNCTION_TRACE("acpi_system_read_dsdt"); - - status = acpi_get_table(ACPI_TABLE_DSDT, 1, &dsdt); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - if (*ppos < dsdt.length) { - data = dsdt.pointer + file->f_pos; - size = dsdt.length - file->f_pos; - if (size > count) - size = count; - if (copy_to_user(buffer, data, size)) { - kfree(dsdt.pointer); - return_VALUE(-EFAULT); - } - } - - kfree(dsdt.pointer); - - *ppos += size; - - return_VALUE(size); -} - - -static ssize_t acpi_system_read_fadt (struct file*, char*, size_t, loff_t*); - -static struct file_operations acpi_system_fadt_ops = { - read: acpi_system_read_fadt, -}; - -static ssize_t -acpi_system_read_fadt ( - struct file *file, - char *buffer, - size_t count, - loff_t *ppos) -{ - acpi_status status = AE_OK; - acpi_buffer fadt = {ACPI_ALLOCATE_BUFFER, NULL}; - void *data = 0; - size_t size = 0; - - ACPI_FUNCTION_TRACE("acpi_system_read_fadt"); - - status = acpi_get_table(ACPI_TABLE_FADT, 1, &fadt); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - if (*ppos < fadt.length) { - data = fadt.pointer + file->f_pos; - size = fadt.length - file->f_pos; - if (size > count) - size = count; - if (copy_to_user(buffer, data, size)) { - kfree(fadt.pointer); - return_VALUE(-EFAULT); - } - } - - kfree(fadt.pointer); - - *ppos += size; - - return_VALUE(size); -} - - -#ifdef ACPI_DEBUG - -static int -acpi_system_read_debug ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - char *p = page; - int size = 0; - - if (off != 0) - goto end; - - switch ((unsigned long) data) { - case 0: - p += sprintf(p, "0x%08x\n", acpi_dbg_layer); - break; - case 1: - p += sprintf(p, "0x%08x\n", acpi_dbg_level); - break; - default: - p += sprintf(p, "Invalid debug option\n"); - break; - } - -end: - size = (p - page); - if (size <= off+count) *eof = 1; - *start = page + off; - size -= off; - if (size>count) size = count; - if (size<0) size = 0; - - return size; -} - - -static int -acpi_system_write_debug ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - char debug_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_system_write_debug"); - - if (count > sizeof(debug_string) - 1) - return_VALUE(-EINVAL); - - if (copy_from_user(debug_string, buffer, count)) - return_VALUE(-EFAULT); - - debug_string[count] = '\0'; - - switch ((unsigned long) data) { - case 0: - acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); - break; - case 1: - acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); - break; - default: - return_VALUE(-EINVAL); - } - - return_VALUE(count); -} - -#endif /* ACPI_DEBUG */ - - -#ifdef CONFIG_ACPI_SLEEP - -static int -acpi_system_read_sleep ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_system *system = (struct acpi_system *) data; - char *p = page; - int size; - int i; - - ACPI_FUNCTION_TRACE("acpi_system_read_sleep"); - - if (!system || (off != 0)) - goto end; - - for (i = 0; i <= ACPI_STATE_S5; i++) { - if (system->states[i]) - p += sprintf(p,"S%d ", i); - } - - p += sprintf(p, "\n"); - -end: - size = (p - page); - if (size <= off+count) *eof = 1; - *start = page + off; - size -= off; - if (size>count) size = count; - if (size<0) size = 0; - - return_VALUE(size); -} - - -static int -acpi_system_write_sleep ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - acpi_status status = AE_OK; - struct acpi_system *system = (struct acpi_system *) data; - char state_string[12] = {'\0'}; - u32 state = 0; - - ACPI_FUNCTION_TRACE("acpi_system_write_sleep"); - - if (!system || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - - state = simple_strtoul(state_string, NULL, 0); - - if (!system->states[state]) - return_VALUE(-ENODEV); - - status = acpi_suspend(state); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - return_VALUE(count); -} - - -static int -acpi_system_read_alarm ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *context) -{ - char *p = page; - int size = 0; - u32 sec, min, hr; - u32 day, mo, yr; - - ACPI_FUNCTION_TRACE("acpi_system_read_alarm"); - - if (off != 0) - goto end; - - spin_lock(&rtc_lock); - - sec = CMOS_READ(RTC_SECONDS_ALARM); - min = CMOS_READ(RTC_MINUTES_ALARM); - hr = CMOS_READ(RTC_HOURS_ALARM); - -#if 0 /* If we ever get an FACP with proper values... */ - if (acpi_gbl_FADT->day_alrm) - day = CMOS_READ(acpi_gbl_FADT->day_alrm); - else - day = CMOS_READ(RTC_DAY_OF_MONTH); - if (acpi_gbl_FADT->mon_alrm) - mo = CMOS_READ(acpi_gbl_FADT->mon_alrm); - else - mo = CMOS_READ(RTC_MONTH);; - if (acpi_gbl_FADT->century) - yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR); - else - yr = CMOS_READ(RTC_YEAR); -#else - day = CMOS_READ(RTC_DAY_OF_MONTH); - mo = CMOS_READ(RTC_MONTH); - yr = CMOS_READ(RTC_YEAR); -#endif - - spin_unlock(&rtc_lock); - - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hr); - BCD_TO_BIN(day); - BCD_TO_BIN(mo); - BCD_TO_BIN(yr); - -#if 0 - /* we're trusting the FADT (see above)*/ -#else - /* If we're not trusting the FADT, we should at least make it - * right for _this_ century... ehm, what is _this_ century? - * - * TBD: - * ASAP: find piece of code in the kernel, e.g. star tracker driver, - * which we can trust to determine the century correctly. Atom - * watch driver would be nice, too... - * - * if that has not happened, change for first release in 2050: - * if (yr<50) - * yr += 2100; - * else - * yr += 2000; // current line of code - * - * if that has not happened either, please do on 2099/12/31:23:59:59 - * s/2000/2100 - * - */ - yr += 2000; -#endif - - p += sprintf(p,"%4.4u-", yr); - p += (mo > 12) ? sprintf(p, "**-") : sprintf(p, "%2.2u-", mo); - p += (day > 31) ? sprintf(p, "** ") : sprintf(p, "%2.2u ", day); - p += (hr > 23) ? sprintf(p, "**:") : sprintf(p, "%2.2u:", hr); - p += (min > 59) ? sprintf(p, "**:") : sprintf(p, "%2.2u:", min); - p += (sec > 59) ? sprintf(p, "**\n") : sprintf(p, "%2.2u\n", sec); - - end: - size = p - page; - if (size < count) *eof = 1; - else if (size > count) size = count; - if (size < 0) size = 0; - *start = page; - - return_VALUE(size); -} - - -static int -get_date_field ( - char **p, - u32 *value) -{ - char *next = NULL; - char *string_end = NULL; - int result = -EINVAL; - - /* - * Try to find delimeter, only to insert null. The end of the - * string won't have one, but is still valid. - */ - next = strpbrk(*p, "- :"); - if (next) - *next++ = '\0'; - - *value = simple_strtoul(*p, &string_end, 10); - - /* Signal success if we got a good digit */ - if (string_end != *p) - result = 0; - - if (next) - *p = next; - - return result; -} - - -static int -acpi_system_write_alarm ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - char alarm_string[30] = {'\0'}; - char *p = alarm_string; - u32 sec, min, hr, day, mo, yr; - int adjust = 0; - unsigned char rtc_control = 0; - - ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); - - if (count > sizeof(alarm_string) - 1) - return_VALUE(-EINVAL); - - if (copy_from_user(alarm_string, buffer, count)) - return_VALUE(-EFAULT); - - alarm_string[count] = '\0'; - - /* check for time adjustment */ - if (alarm_string[0] == '+') { - p++; - adjust = 1; - } - - if ((result = get_date_field(&p, &yr))) - goto end; - if ((result = get_date_field(&p, &mo))) - goto end; - if ((result = get_date_field(&p, &day))) - goto end; - if ((result = get_date_field(&p, &hr))) - goto end; - if ((result = get_date_field(&p, &min))) - goto end; - if ((result = get_date_field(&p, &sec))) - goto end; - - if (sec > 59) { - min += 1; - sec -= 60; - } - if (min > 59) { - hr += 1; - min -= 60; - } - if (hr > 23) { - day += 1; - hr -= 24; - } - if (day > 31) { - mo += 1; - day -= 31; - } - if (mo > 12) { - yr += 1; - mo -= 12; - } - - spin_lock_irq(&rtc_lock); - - rtc_control = CMOS_READ(RTC_CONTROL); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - if (adjust) { - yr += CMOS_READ(RTC_YEAR); - mo += CMOS_READ(RTC_MONTH); - day += CMOS_READ(RTC_DAY_OF_MONTH); - hr += CMOS_READ(RTC_HOURS); - min += CMOS_READ(RTC_MINUTES); - sec += CMOS_READ(RTC_SECONDS); - } - - spin_unlock_irq(&rtc_lock); - - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(yr); - BCD_TO_BIN(mo); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - } - - if (sec > 59) { - min++; - sec -= 60; - } - if (min > 59) { - hr++; - min -= 60; - } - if (hr > 23) { - day++; - hr -= 24; - } - if (day > 31) { - mo++; - day -= 31; - } - if (mo > 12) { - yr++; - mo -= 12; - } - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } - - spin_lock_irq(&rtc_lock); - - /* write the fields the rtc knows about */ - CMOS_WRITE(hr, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - CMOS_WRITE(sec, RTC_SECONDS_ALARM); - - /* - * If the system supports an enhanced alarm it will have non-zero - * offsets into the CMOS RAM here -- which for some reason are pointing - * to the RTC area of memory. - */ -#if 0 - if (acpi_gbl_FADT->day_alrm) - CMOS_WRITE(day, acpi_gbl_FADT->day_alrm); - if (acpi_gbl_FADT->mon_alrm) - CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm); - if (acpi_gbl_FADT->century) - CMOS_WRITE(yr/100, acpi_gbl_FADT->century); -#endif - /* enable the rtc alarm interrupt */ - if (!(rtc_control & RTC_AIE)) { - rtc_control |= RTC_AIE; - CMOS_WRITE(rtc_control,RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); - } - - spin_unlock_irq(&rtc_lock); - - acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); - - file->f_pos += count; - - result = 0; -end: - return_VALUE(result ? result : count); -} - -#endif /*CONFIG_ACPI_SLEEP*/ - - -static int -acpi_system_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_system_add_fs"); - - if (!device) - return_VALUE(-EINVAL); - - /* 'info' [R] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_INFO, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_INFO)); - else { - entry->read_proc = acpi_system_read_info; - entry->data = acpi_driver_data(device); - } - - /* 'dsdt' [R] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_DSDT, - S_IRUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_DSDT)); - else - entry->proc_fops = &acpi_system_dsdt_ops; - - /* 'fadt' [R] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_FADT, - S_IRUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_FADT)); - else - entry->proc_fops = &acpi_system_fadt_ops; - - /* 'event' [R] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_EVENT, - S_IRUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_EVENT)); - else - entry->proc_fops = &acpi_system_event_ops; - -#ifdef CONFIG_ACPI_SLEEP - - /* 'sleep' [R/W]*/ - entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_SLEEP)); - else { - entry->read_proc = acpi_system_read_sleep; - entry->write_proc = acpi_system_write_sleep; - entry->data = acpi_driver_data(device); - } - - /* 'alarm' [R/W] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_ALARM)); - else { - entry->read_proc = acpi_system_read_alarm; - entry->write_proc = acpi_system_write_alarm; - entry->data = acpi_driver_data(device); - } - -#endif /*CONFIG_ACPI_SLEEP*/ - -#ifdef ACPI_DEBUG - - /* 'debug_layer' [R/W] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_DEBUG_LAYER)); - else { - entry->read_proc = acpi_system_read_debug; - entry->write_proc = acpi_system_write_debug; - entry->data = (void *) 0; - } - - /* 'debug_level' [R/W] */ - entry = create_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_SYSTEM_FILE_DEBUG_LEVEL)); - else { - entry->read_proc = acpi_system_read_debug; - entry->write_proc = acpi_system_write_debug; - entry->data = (void *) 1; - } - -#endif /*ACPI_DEBUG*/ - - return_VALUE(0); -} - - -static int -acpi_system_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_system_remove_fs"); - - if (!device) - return_VALUE(-EINVAL); - - remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_device_dir(device)); - remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_device_dir(device)); - remove_proc_entry(ACPI_SYSTEM_FILE_EVENT, acpi_device_dir(device)); -#ifdef CONFIG_ACPI_SLEEP - remove_proc_entry(ACPI_SYSTEM_FILE_SLEEP, acpi_device_dir(device)); - remove_proc_entry(ACPI_SYSTEM_FILE_ALARM, acpi_device_dir(device)); -#endif -#ifdef ACPI_DEBUG - remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, - acpi_device_dir(device)); - remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, - acpi_device_dir(device)); -#endif - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -#if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_PM) - -/* Simple wrapper calling power down function. */ -static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs, - struct kbd_struct *kbd, struct tty_struct *tty) -{ - acpi_power_off(); -} - -struct sysrq_key_op sysrq_acpi_poweroff_op = { - handler: &acpi_sysrq_power_off, - help_msg: "Off", - action_msg: "Power Off\n" -}; - -#endif /* CONFIG_MAGIC_SYSRQ */ - -static int -acpi_system_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_system *system = NULL; - u8 i = 0; - - ACPI_FUNCTION_TRACE("acpi_system_add"); - - if (!device) - return_VALUE(-EINVAL); - - system = kmalloc(sizeof(struct acpi_system), GFP_KERNEL); - if (!system) - return_VALUE(-ENOMEM); - memset(system, 0, sizeof(struct acpi_system)); - - system->handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_SYSTEM_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_SYSTEM_CLASS); - acpi_driver_data(device) = system; - - result = acpi_system_add_fs(device); - if (0 != result) - goto end; - - printk(KERN_INFO PREFIX "%s [%s] (supports", - acpi_device_name(device), acpi_device_bid(device)); - for (i=0; istates[i] = 1; - printk(" S%d", i); - } - } - printk(")\n"); - -#ifdef CONFIG_PM - /* Install the soft-off (S5) handler. */ - if (system->states[ACPI_STATE_S5]) { - pm_power_off = acpi_power_off; - register_sysrq_key('o', &sysrq_acpi_poweroff_op); - } -#endif - -end: - if (0 != result) - kfree(system); - - return_VALUE(result); -} - - -static int -acpi_system_remove ( - struct acpi_device *device, - int type) -{ - struct acpi_system *system = NULL; - - ACPI_FUNCTION_TRACE("acpi_system_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - system = (struct acpi_system *) acpi_driver_data(device); - -#ifdef CONFIG_PM - /* Remove the soft-off (S5) handler. */ - if (system->states[ACPI_STATE_S5]) { - unregister_sysrq_key('o', &sysrq_acpi_poweroff_op); - pm_power_off = NULL; - } -#endif - - acpi_system_remove_fs(device); - - kfree(system); - - return 0; -} - - -int __init -acpi_system_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_system_init"); - - result = acpi_bus_register_driver(&acpi_system_driver); - if (0 > result) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -void __exit -acpi_system_exit (void) -{ - ACPI_FUNCTION_TRACE("acpi_system_exit"); - acpi_bus_unregister_driver(&acpi_system_driver); - return_VOID; -} diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,475 +0,0 @@ -/* - * acpi_tables.c - ACPI Boot-Time Table Parsing - * - * Copyright (C) 2001 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PREFIX "ACPI: " - -#define ACPI_MAX_TABLES ACPI_TABLE_COUNT - -static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { - [ACPI_TABLE_UNKNOWN] = "????", - [ACPI_APIC] = "APIC", - [ACPI_BOOT] = "BOOT", - [ACPI_DBGP] = "DBGP", - [ACPI_DSDT] = "DSDT", - [ACPI_ECDT] = "ECDT", - [ACPI_ETDT] = "ETDT", - [ACPI_FACP] = "FACP", - [ACPI_FACS] = "FACS", - [ACPI_OEMX] = "OEM", - [ACPI_PSDT] = "PSDT", - [ACPI_SBST] = "SBST", - [ACPI_SLIT] = "SLIT", - [ACPI_SPCR] = "SPCR", - [ACPI_SRAT] = "SRAT", - [ACPI_SSDT] = "SSDT", - [ACPI_SPMI] = "SPMI" -}; - -/* System Description Table (RSDT/XSDT) */ -struct acpi_table_sdt { - unsigned long pa; /* Physical Address */ - unsigned long count; /* Table count */ - struct { - unsigned long pa; - enum acpi_table_id id; - unsigned long size; - } entry[ACPI_MAX_TABLES]; -} __attribute__ ((packed)); - -static struct acpi_table_sdt sdt; - -acpi_madt_entry_handler madt_handlers[ACPI_MADT_ENTRY_COUNT]; - - -void -acpi_table_print ( - struct acpi_table_header *header, - unsigned long phys_addr) -{ - char *name = NULL; - - if (!header) - return; - - /* Some table signatures aren't good table names */ - - if (0 == strncmp((char *) &header->signature, - acpi_table_signatures[ACPI_APIC], - sizeof(header->signature))) { - name = "MADT"; - } - else if (0 == strncmp((char *) &header->signature, - acpi_table_signatures[ACPI_FACP], - sizeof(header->signature))) { - name = "FADT"; - } - else - name = header->signature; - - printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s %5.5d.%5.5d) @ 0x%p\n", - name, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision >> 16, - header->oem_revision & 0xffff, (void *) phys_addr); -} - - -void -acpi_table_print_madt_entry ( - acpi_table_entry_header *header) -{ - if (!header) - return; - - switch (header->type) { - - case ACPI_MADT_LAPIC: - { - struct acpi_table_lapic *p = - (struct acpi_table_lapic*) header; - printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled"); - } - break; - - case ACPI_MADT_IOAPIC: - { - struct acpi_table_ioapic *p = - (struct acpi_table_ioapic*) header; - printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] global_irq_base[0x%x])\n", - p->id, p->address, p->global_irq_base); - } - break; - - case ACPI_MADT_INT_SRC_OVR: - { - struct acpi_table_int_src_ovr *p = - (struct acpi_table_int_src_ovr*) header; - printk(KERN_INFO PREFIX "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n", - p->bus, p->bus_irq, p->global_irq, p->flags.polarity, p->flags.trigger); - } - break; - - case ACPI_MADT_NMI_SRC: - { - struct acpi_table_nmi_src *p = - (struct acpi_table_nmi_src*) header; - printk(KERN_INFO PREFIX "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n", - p->flags.polarity, p->flags.trigger, p->global_irq); - } - break; - - case ACPI_MADT_LAPIC_NMI: - { - struct acpi_table_lapic_nmi *p = - (struct acpi_table_lapic_nmi*) header; - printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n", - p->acpi_id, p->flags.polarity, p->flags.trigger, p->lint); - } - break; - - case ACPI_MADT_LAPIC_ADDR_OVR: - { - struct acpi_table_lapic_addr_ovr *p = - (struct acpi_table_lapic_addr_ovr*) header; - printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", - (void *) (unsigned long) p->address); - } - break; - - case ACPI_MADT_IOSAPIC: - { - struct acpi_table_iosapic *p = - (struct acpi_table_iosapic*) header; - printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] global_irq_base[0x%x] address[%p])\n", - p->id, p->global_irq_base, (void *) (unsigned long) p->address); - } - break; - - case ACPI_MADT_LSAPIC: - { - struct acpi_table_lsapic *p = - (struct acpi_table_lsapic*) header; - printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled"); - } - break; - - case ACPI_MADT_PLAT_INT_SRC: - { - struct acpi_table_plat_int_src *p = - (struct acpi_table_plat_int_src*) header; - printk(KERN_INFO PREFIX "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - p->flags.polarity, p->flags.trigger, p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); - } - break; - - default: - printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n", - header->type); - break; - } -} - - -static int -acpi_table_compute_checksum ( - void *table_pointer, - unsigned long length) -{ - u8 *p = (u8 *) table_pointer; - unsigned long remains = length; - unsigned long sum = 0; - - if (!p || !length) - return -EINVAL; - - while (remains--) - sum += *p++; - - return (sum & 0xFF); -} - - -int __init -acpi_table_parse_madt ( - enum acpi_table_id id, - acpi_madt_entry_handler handler) -{ - struct acpi_table_madt *madt = NULL; - acpi_table_entry_header *entry = NULL; - unsigned long count = 0; - unsigned long madt_end = 0; - int i = 0; - - if (!handler) - return -EINVAL; - - /* Locate the MADT (if exists). There should only be one. */ - - for (i = 0; i < sdt.count; i++) { - if (sdt.entry[i].id != ACPI_APIC) - continue; - madt = (struct acpi_table_madt *) - __acpi_map_table(sdt.entry[i].pa, sdt.entry[i].size); - if (!madt) { - printk(KERN_WARNING PREFIX "Unable to map MADT\n"); - return -ENODEV; - } - break; - } - - if (!madt) { - printk(KERN_WARNING PREFIX "MADT not present\n"); - return -ENODEV; - } - - madt_end = (unsigned long) madt + sdt.entry[i].size; - - /* Parse all entries looking for a match. */ - - entry = (acpi_table_entry_header *) - ((unsigned long) madt + sizeof(struct acpi_table_madt)); - - while (((unsigned long) entry) < madt_end) { - if (entry->type == id) { - count++; - handler(entry); - } - entry = (acpi_table_entry_header *) - ((unsigned long) entry += entry->length); - } - - return count; -} - - -int __init -acpi_table_parse ( - enum acpi_table_id id, - acpi_table_handler handler) -{ - int count = 0; - int i = 0; - - if (!handler) - return -EINVAL; - - for (i = 0; i < sdt.count; i++) { - if (sdt.entry[i].id != id) - continue; - handler(sdt.entry[i].pa, sdt.entry[i].size); - count++; - } - - return count; -} - - -static int __init -acpi_table_get_sdt ( - struct acpi_table_rsdp *rsdp) -{ - struct acpi_table_header *header = NULL; - int i, id = 0; - - if (!rsdp) - return -EINVAL; - - /* First check XSDT (but only on ACPI 2.0-compatible systems) */ - - if ((rsdp->revision >= 2) && - (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) { - - struct acpi_table_xsdt *mapped_xsdt = NULL; - - sdt.pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address; - - header = (struct acpi_table_header *) - __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); - - if (!header) { - printk(KERN_WARNING PREFIX "Unable to map XSDT header\n"); - return -ENODEV; - } - - if (strncmp(header->signature, "XSDT", 4)) { - printk(KERN_WARNING PREFIX "XSDT signature incorrect\n"); - return -ENODEV; - } - - sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; - if (sdt.count > ACPI_MAX_TABLES) { - printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n", - (ACPI_MAX_TABLES - sdt.count)); - sdt.count = ACPI_MAX_TABLES; - } - - mapped_xsdt = (struct acpi_table_xsdt *) - __acpi_map_table(sdt.pa, header->length); - if (!mapped_xsdt) { - printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); - return -ENODEV; - } - - header = &mapped_xsdt->header; - - for (i = 0; i < sdt.count; i++) - sdt.entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; - } - - /* Then check RSDT */ - - else if (rsdp->rsdt_address) { - - struct acpi_table_rsdt *mapped_rsdt = NULL; - - sdt.pa = rsdp->rsdt_address; - - header = (struct acpi_table_header *) - __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); - if (!header) { - printk(KERN_WARNING PREFIX "Unable to map RSDT header\n"); - return -ENODEV; - } - - if (strncmp(header->signature, "RSDT", 4)) { - printk(KERN_WARNING PREFIX "RSDT signature incorrect\n"); - return -ENODEV; - } - - sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 2; - if (sdt.count > ACPI_MAX_TABLES) { - printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n", - (ACPI_TABLE_COUNT - sdt.count)); - sdt.count = ACPI_MAX_TABLES; - } - - mapped_rsdt = (struct acpi_table_rsdt *) - __acpi_map_table(sdt.pa, header->length); - if (!mapped_rsdt) { - printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); - return -ENODEV; - } - - header = &mapped_rsdt->header; - - for (i = 0; i < sdt.count; i++) - sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; - } - - else { - printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n"); - return -ENODEV; - } - - acpi_table_print(header, sdt.pa); - - for (i = 0; i < sdt.count; i++) { - - header = (struct acpi_table_header *) - __acpi_map_table(sdt.entry[i].pa, - sizeof(struct acpi_table_header)); - if (!header) - continue; - - acpi_table_print(header, sdt.entry[i].pa); - - if (0 != acpi_table_compute_checksum(header, header->length)) { - printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); - continue; - } - - sdt.entry[i].size = header->length; - - for (id = 0; id < ACPI_TABLE_COUNT; id++) { - if (0 == strncmp((char *) &header->signature, - acpi_table_signatures[id], - sizeof(header->signature))) { - sdt.entry[i].id = id; - } - } - } - - return 0; -} - - -int __init -acpi_table_init ( - char *cmdline) -{ - struct acpi_table_rsdp *rsdp = NULL; - unsigned long rsdp_phys = 0; - int result = 0; - - memset(&sdt, 0, sizeof(struct acpi_table_sdt)); - memset(&madt_handlers, 0, sizeof(madt_handlers)); - - /* Locate and map the Root System Description Table (RSDP) */ - - rsdp_phys = acpi_find_rsdp(); - if (!rsdp_phys) { - printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); - return -ENODEV; - } - - rsdp = (struct acpi_table_rsdp *) __va(rsdp_phys); - if (!rsdp) { - printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); - return -ENODEV; - } - - printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", - rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); - - if (rsdp->revision < 2) - result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp)); - else - result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length); - - if (0 != result) { - printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); - return -ENODEV; - } - - /* Locate and map the System Description table (RSDT/XSDT) */ - - if (0 != acpi_table_get_sdt(rsdp)) - return -ENODEV; - - return 0; -} - diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1318 +0,0 @@ -/* - * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 36 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This driver fully implements the ACPI thermal policy as described in the - * ACPI 2.0 Specification. - * - * TBD: 1. Implement passive cooling hysteresis. - * 2. Enhance passive cooling (CPU) states/limit interface to support - * concepts of 'multiple limiters', upper/lower limits, etc. - * - */ - -#include -#include -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_THERMAL_COMPONENT -ACPI_MODULE_NAME ("acpi_thermal") - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -static int tzp = 0; -MODULE_PARM(tzp, "i"); -MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); - -#define PREFIX "ACPI: " - - -#define ACPI_THERMAL_MAX_ACTIVE 10 - -#define KELVIN_TO_CELSIUS(t) ((t-2732+5)/10) - -static int acpi_thermal_add (struct acpi_device *device); -static int acpi_thermal_remove (struct acpi_device *device, int type); - -static struct acpi_driver acpi_thermal_driver = { - name: ACPI_THERMAL_DRIVER_NAME, - class: ACPI_THERMAL_CLASS, - ids: ACPI_THERMAL_HID, - ops: { - add: acpi_thermal_add, - remove: acpi_thermal_remove, - }, -}; - -struct acpi_thermal_state { - u8 critical:1; - u8 hot:1; - u8 passive:1; - u8 active:1; - u8 reserved:4; - int active_index; -}; - -struct acpi_thermal_state_flags { - u8 valid:1; - u8 enabled:1; - u8 reserved:6; -}; - -struct acpi_thermal_critical { - struct acpi_thermal_state_flags flags; - unsigned long temperature; -}; - -struct acpi_thermal_hot { - struct acpi_thermal_state_flags flags; - unsigned long temperature; -}; - -struct acpi_thermal_passive { - struct acpi_thermal_state_flags flags; - unsigned long temperature; - unsigned long tc1; - unsigned long tc2; - unsigned long tsp; - struct acpi_handle_list devices; -}; - -struct acpi_thermal_active { - struct acpi_thermal_state_flags flags; - unsigned long temperature; - struct acpi_handle_list devices; -}; - -struct acpi_thermal_trips { - struct acpi_thermal_critical critical; - struct acpi_thermal_hot hot; - struct acpi_thermal_passive passive; - struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; -}; - -struct acpi_thermal_flags { - u8 cooling_mode:1; /* _SCP */ - u8 devices:1; /* _TZD */ - u8 reserved:6; -}; - -struct acpi_thermal { - acpi_handle handle; - acpi_bus_id name; - unsigned long temperature; - unsigned long last_temperature; - unsigned long polling_frequency; - u8 cooling_mode; - struct acpi_thermal_flags flags; - struct acpi_thermal_state state; - struct acpi_thermal_trips trips; - struct acpi_handle_list devices; - struct timer_list timer; -}; - - -/* -------------------------------------------------------------------------- - Thermal Zone Management - -------------------------------------------------------------------------- */ - -static int -acpi_thermal_get_temperature ( - struct acpi_thermal *tz) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature"); - - if (!tz) - return_VALUE(-EINVAL); - - tz->last_temperature = tz->temperature; - - status = acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature); - if (ACPI_FAILURE(status)) - return -ENODEV; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", tz->temperature)); - - return_VALUE(0); -} - - -static int -acpi_thermal_get_polling_frequency ( - struct acpi_thermal *tz) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency"); - - if (!tz) - return_VALUE(-EINVAL); - - status = acpi_evaluate_integer(tz->handle, "_TZP", NULL, &tz->polling_frequency); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", tz->polling_frequency)); - - return_VALUE(0); -} - - -static int -acpi_thermal_set_polling ( - struct acpi_thermal *tz, - int seconds) -{ - ACPI_FUNCTION_TRACE("acpi_thermal_set_polling"); - - if (!tz) - return_VALUE(-EINVAL); - - tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency set to %lu seconds\n", tz->polling_frequency)); - - return_VALUE(0); -} - - -static int -acpi_thermal_set_cooling_mode ( - struct acpi_thermal *tz, - int mode) -{ - acpi_status status = AE_OK; - acpi_object arg0 = {ACPI_TYPE_INTEGER}; - acpi_object_list arg_list= {1, &arg0}; - acpi_handle handle = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode"); - - if (!tz) - return_VALUE(-EINVAL); - - status = acpi_get_handle(tz->handle, "_SCP", &handle); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); - return_VALUE(-ENODEV); - } - - arg0.integer.value = mode; - - status = acpi_evaluate(handle, NULL, &arg_list, NULL); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - tz->cooling_mode = mode; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", - mode?"passive":"active")); - - return_VALUE(0); -} - - -static int -acpi_thermal_get_trip_points ( - struct acpi_thermal *tz) -{ - acpi_status status = AE_OK; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points"); - - if (!tz) - return_VALUE(-EINVAL); - - /* Critical Shutdown (required) */ - - status = acpi_evaluate_integer(tz->handle, "_CRT", NULL, - &tz->trips.critical.temperature); - if (ACPI_FAILURE(status)) { - tz->trips.critical.flags.valid = 0; - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n")); - return -ENODEV; - } - else { - tz->trips.critical.flags.valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found critical threshold [%lu]\n", tz->trips.critical.temperature)); - } - - /* Critical Sleep (optional) */ - - status = acpi_evaluate_integer(tz->handle, "_HOT", NULL, &tz->trips.hot.temperature); - if (ACPI_FAILURE(status)) { - tz->trips.hot.flags.valid = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n")); - } - else { - tz->trips.hot.flags.valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", tz->trips.hot.temperature)); - } - - /* Passive: Processors (optional) */ - - status = acpi_evaluate_integer(tz->handle, "_PSV", NULL, &tz->trips.passive.temperature); - if (ACPI_FAILURE(status)) { - tz->trips.passive.flags.valid = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); - } - else { - tz->trips.passive.flags.valid = 1; - - status = acpi_evaluate_integer(tz->handle, "_TC1", NULL, &tz->trips.passive.tc1); - if (ACPI_FAILURE(status)) - tz->trips.passive.flags.valid = 0; - - status = acpi_evaluate_integer(tz->handle, "_TC2", NULL, &tz->trips.passive.tc2); - if (ACPI_FAILURE(status)) - tz->trips.passive.flags.valid = 0; - - status = acpi_evaluate_integer(tz->handle, "_TSP", NULL, &tz->trips.passive.tsp); - if (ACPI_FAILURE(status)) - tz->trips.passive.flags.valid = 0; - - status = acpi_evaluate_reference(tz->handle, "_PSL", NULL, &tz->trips.passive.devices); - if (ACPI_FAILURE(status)) - tz->trips.passive.flags.valid = 0; - - if (!tz->trips.passive.flags.valid) - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid passive threshold\n")); - else - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found passive threshold [%lu]\n", tz->trips.passive.temperature)); - } - - /* Active: Fans, etc. (optional) */ - - for (i=0; ihandle, name, NULL, &tz->trips.active[i].temperature); - if (ACPI_FAILURE(status)) - break; - - name[2] = 'L'; - status = acpi_evaluate_reference(tz->handle, name, NULL, &tz->trips.active[i].devices); - if (ACPI_SUCCESS(status)) { - tz->trips.active[i].flags.valid = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found active threshold [%d]:[%lu]\n", i, tz->trips.active[i].temperature)); - } - else - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid active threshold [%d]\n", i)); - } - - return_VALUE(0); -} - - -static int -acpi_thermal_get_devices ( - struct acpi_thermal *tz) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_thermal_get_devices"); - - if (!tz) - return_VALUE(-EINVAL); - - status = acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices); - if (ACPI_FAILURE(status)) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -static int -acpi_thermal_call_usermode ( - char *path) -{ - char *argv[2] = {NULL, NULL}; - char *envp[3] = {NULL, NULL, NULL}; - - ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode"); - - if (!path) - return_VALUE(-EINVAL);; - - argv[0] = path; - - /* minimal command environment */ - envp[0] = "HOME=/"; - envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - - call_usermodehelper(argv[0], argv, envp); - - return_VALUE(0); -} - - -static int -acpi_thermal_critical ( - struct acpi_thermal *tz) -{ - int result = 0; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_critical"); - - if (!tz || !tz->trips.critical.flags.valid) - return_VALUE(-EINVAL); - - if (tz->temperature >= tz->trips.critical.temperature) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n")); - tz->trips.critical.flags.enabled = 1; - } - else if (tz->trips.critical.flags.enabled) - tz->trips.critical.flags.enabled = 0; - - result = acpi_bus_get_device(tz->handle, &device); - if (0 != result) - return_VALUE(result); - - acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); - - acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); - - return_VALUE(0); -} - - -static int -acpi_thermal_hot ( - struct acpi_thermal *tz) -{ - int result = 0; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_hot"); - - if (!tz || !tz->trips.hot.flags.valid) - return_VALUE(-EINVAL); - - if (tz->temperature >= tz->trips.hot.temperature) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n")); - tz->trips.hot.flags.enabled = 1; - } - else if (tz->trips.hot.flags.enabled) - tz->trips.hot.flags.enabled = 0; - - result = acpi_bus_get_device(tz->handle, &device); - if (0 != result) - return_VALUE(result); - - acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); - - /* TBD: Call user-mode "sleep(S4)" function */ - - return_VALUE(0); -} - - -static int -acpi_thermal_passive ( - struct acpi_thermal *tz) -{ - int result = 0; - struct acpi_thermal_passive *passive = NULL; - int trend = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_passive"); - - if (!tz || !tz->trips.passive.flags.valid) - return_VALUE(-EINVAL); - - passive = &(tz->trips.passive); - - /* - * Above Trip? - * ----------- - * Calculate the thermal trend (using the passive cooling equation) - * and modify the performance limit for all passive cooling devices - * accordingly. Note that we assume symmetry. - */ - if (tz->temperature >= passive->temperature) { - trend = (passive->tc1 * (tz->temperature - tz->last_temperature)) + (passive->tc2 * (tz->temperature - passive->temperature)); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", - trend, passive->tc1, tz->temperature, - tz->last_temperature, passive->tc2, - tz->temperature, passive->temperature)); - /* Heating up? */ - if (trend > 0) - for (i=0; idevices.count; i++) - acpi_processor_set_thermal_limit( - passive->devices.handles[i], - ACPI_PROCESSOR_LIMIT_INCREMENT); - /* Cooling off? */ - else if (trend < 0) - for (i=0; idevices.count; i++) - acpi_processor_set_thermal_limit( - passive->devices.handles[i], - ACPI_PROCESSOR_LIMIT_DECREMENT); - } - - /* - * Below Trip? - * ----------- - * Implement passive cooling hysteresis to slowly increase performance - * and avoid thrashing around the passive trip point. Note that we - * assume symmetry. - */ - else if (tz->trips.passive.flags.enabled) { - for (i=0; idevices.count; i++) - result = acpi_processor_set_thermal_limit( - passive->devices.handles[i], - ACPI_PROCESSOR_LIMIT_DECREMENT); - if (1 == result) { - tz->trips.passive.flags.enabled = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Disabling passive cooling (zone is cool)\n")); - } - } - - return_VALUE(0); -} - - -static int -acpi_thermal_active ( - struct acpi_thermal *tz) -{ - int result = 0; - struct acpi_thermal_active *active = NULL; - int i = 0; - int j = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_active"); - - if (!tz) - return_VALUE(-EINVAL); - - for (i=0; itrips.active[i]); - if (!active || !active->flags.valid) - break; - - /* - * Above Threshold? - * ---------------- - * If not already enabled, turn ON all cooling devices - * associated with this active threshold. - */ - if (tz->temperature >= active->temperature) { - tz->state.active_index = i; - if (!active->flags.enabled) { - for (j = 0; j < active->devices.count; j++) { - result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'on'\n", active->devices.handles[j])); - continue; - } - active->flags.enabled = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'on'\n", active->devices.handles[j])); - } - } - } - /* - * Below Threshold? - * ---------------- - * Turn OFF all cooling devices associated with this - * threshold. - */ - else if (active->flags.enabled) { - for (j = 0; j < active->devices.count; j++) { - result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3); - if (0 != result) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'off'\n", active->devices.handles[j])); - continue; - } - active->flags.enabled = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'off'\n", active->devices.handles[j])); - } - } - } - - return_VALUE(0); -} - - -static void acpi_thermal_check (void *context); - -static void -acpi_thermal_run ( - unsigned long data) -{ - acpi_os_queue_for_execution(OSD_PRIORITY_GPE, acpi_thermal_check, (void *) data); -} - - -static void -acpi_thermal_check ( - void *data) -{ - int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; - unsigned long sleep_time = 0; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_check"); - - if (!tz) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); - return_VOID; - } - - result = acpi_thermal_get_temperature(tz); - if (0 != result) - return_VOID; - - memset(&tz->state, 0, sizeof(tz->state)); - - /* - * Check Trip Points - * ----------------- - * Compare the current temperature to the trip point values to see - * if we've entered one of the thermal policy states. Note that - * this function determines when a state is entered, but the - * individual policy decides when it is exited (e.g. hysteresis). - */ - if ((tz->trips.critical.flags.valid) && (tz->temperature >= tz->trips.critical.temperature)) - tz->trips.critical.flags.enabled = 1; - if ((tz->trips.hot.flags.valid) && (tz->temperature >= tz->trips.hot.temperature)) - tz->trips.hot.flags.enabled = 1; - if ((tz->trips.passive.flags.valid) && (tz->temperature >= tz->trips.passive.temperature)) - tz->trips.passive.flags.enabled = 1; - for (i=0; itrips.active[i].flags.valid) && (tz->temperature >= tz->trips.active[i].temperature)) - tz->trips.active[i].flags.enabled = 1; - - /* - * Invoke Policy - * ------------- - * Separated from the above check to allow individual policy to - * determine when to exit a given state. - */ - if (tz->trips.critical.flags.enabled) - acpi_thermal_critical(tz); - if (tz->trips.hot.flags.enabled) - acpi_thermal_hot(tz); - if (tz->trips.passive.flags.enabled) - acpi_thermal_passive(tz); - if (tz->trips.active[0].flags.enabled) - acpi_thermal_active(tz); - - /* - * Calculate State - * --------------- - * Again, separated from the above two to allow independent policy - * decisions. - */ - if (tz->trips.critical.flags.enabled) - tz->state.critical = 1; - if (tz->trips.hot.flags.enabled) - tz->state.hot = 1; - if (tz->trips.passive.flags.enabled) - tz->state.passive = 1; - for (i=0; itrips.active[i].flags.enabled) - tz->state.active = 1; - - /* - * Calculate Sleep Time - * -------------------- - * If we're in the passive state, use _TSP's value. Otherwise - * use the default polling frequency (e.g. _TZP). If no polling - * frequency is specified then we'll wait forever (at least until - * a thermal event occurs). Note that _TSP and _TZD values are - * given in 1/10th seconds (we must covert to milliseconds). - */ - if (tz->state.passive) - sleep_time = tz->trips.passive.tsp * 100; - else if (tz->polling_frequency > 0) - sleep_time = tz->polling_frequency * 100; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", - tz->name, tz->temperature, sleep_time)); - - /* - * Schedule Next Poll - * ------------------ - */ - if (!sleep_time) { - if (timer_pending(&(tz->timer))) - del_timer(&(tz->timer)); - } - else { - if (timer_pending(&(tz->timer))) - mod_timer(&(tz->timer), (HZ * sleep_time) / 1000); - else { - tz->timer.data = (unsigned long) tz; - tz->timer.function = acpi_thermal_run; - tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; - add_timer(&(tz->timer)); - } - } - - return_VOID; -} - - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#include -#include - -struct proc_dir_entry *acpi_thermal_dir = NULL; - - -static int -acpi_thermal_read_state ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_read_state"); - - if (!tz || (off != 0)) - goto end; - - p += sprintf(p, "state: "); - - if (!tz->state.critical && !tz->state.hot && !tz->state.passive && !tz->state.active) - p += sprintf(p, "ok\n"); - else { - if (tz->state.critical) - p += sprintf(p, "critical "); - if (tz->state.hot) - p += sprintf(p, "hot "); - if (tz->state.passive) - p += sprintf(p, "passive "); - if (tz->state.active) - p += sprintf(p, "active[%d]", tz->state.active_index); - p += sprintf(p, "\n"); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_thermal_read_temperature ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_read_temperature"); - - if (!tz || (off != 0)) - goto end; - - result = acpi_thermal_get_temperature(tz); - if (0 != result) - goto end; - - p += sprintf(p, "temperature: %lu C\n", - KELVIN_TO_CELSIUS(tz->temperature)); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_thermal_read_trip_points ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char *p = page; - int len = 0; - int i = 0; - int j = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_read_trip_points"); - - if (!tz || (off != 0)) - goto end; - - if (tz->trips.critical.flags.valid) - p += sprintf(p, "critical (S5): %lu C\n", - KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); - - if (tz->trips.hot.flags.valid) - p += sprintf(p, "hot (S4): %lu C\n", - KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); - - if (tz->trips.passive.flags.valid) { - p += sprintf(p, "passive: %lu C: tc1=%lu tc2=%lu tsp=%lu devices=", - KELVIN_TO_CELSIUS(tz->trips.passive.temperature), - tz->trips.passive.tc1, - tz->trips.passive.tc2, - tz->trips.passive.tsp); - for (j=0; jtrips.passive.devices.count; j++) { - - p += sprintf(p, "0x%p ", tz->trips.passive.devices.handles[j]); - } - p += sprintf(p, "\n"); - } - - for (i=0; itrips.active[i].flags.valid)) - break; - p += sprintf(p, "active[%d]: %lu C: devices=", - i, KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); - for (j=0; jtrips.active[i].devices.count; j++) - p += sprintf(p, "0x%p ", - tz->trips.active[i].devices.handles[j]); - p += sprintf(p, "\n"); - } - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_thermal_read_cooling_mode ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_read_cooling_mode"); - - if (!tz || (off != 0)) - goto end; - - if (!tz->flags.cooling_mode) { - p += sprintf(p, "\n"); - goto end; - } - - p += sprintf(p, "cooling mode: %s\n", - tz->cooling_mode?"passive":"active"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_thermal_write_cooling_mode ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char mode_string[12] = {'\0'}; - - ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode"); - - if (!tz || (count > sizeof(mode_string) - 1)) - return_VALUE(-EINVAL); - - if (!tz->flags.cooling_mode) - return_VALUE(-ENODEV); - - if (copy_from_user(mode_string, buffer, count)) - return_VALUE(-EFAULT); - - mode_string[count] = '\0'; - - result = acpi_thermal_set_cooling_mode(tz, - simple_strtoul(mode_string, NULL, 0)); - if (0 != result) - return_VALUE(result); - - return_VALUE(count); -} - - -static int -acpi_thermal_read_polling ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) -{ - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char *p = page; - int len = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_read_polling"); - - if (!tz || (off != 0)) - goto end; - - if (!tz->polling_frequency) { - p += sprintf(p, "\n"); - goto end; - } - - p += sprintf(p, "polling frequency: %lu seconds\n", - (tz->polling_frequency / 10)); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); -} - - -static int -acpi_thermal_write_polling ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *) data; - char polling_string[12] = {'\0'}; - int seconds = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_write_polling"); - - if (!tz || (count > sizeof(polling_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(polling_string, buffer, count)) - return_VALUE(-EFAULT); - - polling_string[count] = '\0'; - - seconds = simple_strtoul(polling_string, NULL, 0); - - result = acpi_thermal_set_polling(tz, seconds); - if (0 != result) - return_VALUE(result); - - acpi_thermal_check(tz); - - return_VALUE(count); -} - - -static int -acpi_thermal_add_fs ( - struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_add_fs"); - - if (!acpi_thermal_dir) { - acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, - acpi_root_dir); - if (!acpi_thermal_dir) - return_VALUE(-ENODEV); - } - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_thermal_dir); - if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); - } - - /* 'state' [R] */ - entry = create_proc_entry(ACPI_THERMAL_FILE_STATE, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_STATE)); - else { - entry->read_proc = acpi_thermal_read_state; - entry->data = acpi_driver_data(device); - } - - /* 'temperature' [R] */ - entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_TEMPERATURE)); - else { - entry->read_proc = acpi_thermal_read_temperature; - entry->data = acpi_driver_data(device); - } - - /* 'trip_points' [R] */ - entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, - S_IRUGO, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_POLLING_FREQ)); - else { - entry->read_proc = acpi_thermal_read_trip_points; - entry->data = acpi_driver_data(device); - } - - /* 'cooling_mode' [R/W] */ - entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_COOLING_MODE)); - else { - entry->read_proc = acpi_thermal_read_cooling_mode; - entry->write_proc = acpi_thermal_write_cooling_mode; - entry->data = acpi_driver_data(device); - } - - /* 'polling_frequency' [R/W] */ - entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_POLLING_FREQ)); - else { - entry->read_proc = acpi_thermal_read_polling; - entry->write_proc = acpi_thermal_write_polling; - entry->data = acpi_driver_data(device); - } - - return_VALUE(0); -} - - -static int -acpi_thermal_remove_fs ( - struct acpi_device *device) -{ - ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs"); - - if (!acpi_thermal_dir) - return_VALUE(-ENODEV); - - if (acpi_device_dir(device)) - remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); - - return_VALUE(0); -} - - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static void -acpi_thermal_notify ( - acpi_handle handle, - u32 event, - void *data) -{ - struct acpi_thermal *tz = (struct acpi_thermal *) data; - struct acpi_device *device = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_notify"); - - if (!tz) - return_VOID; - - if (0 != acpi_bus_get_device(tz->handle, &device)) - return_VOID; - - switch (event) { - case ACPI_THERMAL_NOTIFY_TEMPERATURE: - acpi_thermal_check(tz); - break; - case ACPI_THERMAL_NOTIFY_THRESHOLDS: - acpi_thermal_get_trip_points(tz); - acpi_thermal_check(tz); - acpi_bus_generate_event(device, event, 0); - break; - case ACPI_THERMAL_NOTIFY_DEVICES: - if (tz->flags.devices) - acpi_thermal_get_devices(tz); - acpi_bus_generate_event(device, event, 0); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return_VOID; -} - - -static int -acpi_thermal_get_info ( - struct acpi_thermal *tz) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_get_info"); - - if (!tz) - return_VALUE(-EINVAL); - - /* Get temperature [_TMP] (required) */ - result = acpi_thermal_get_temperature(tz); - if (0 != result) - return_VALUE(result); - - /* Set the cooling mode [_SCP] to active cooling (default) */ - result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); - if (0 == result) - tz->flags.cooling_mode = 1; - - /* Get trip points [_CRT, _PSV, etc.] (required) */ - result = acpi_thermal_get_trip_points(tz); - if (0 != result) - return_VALUE(result); - - /* Get default polling frequency [_TZP] (optional) */ - if (tzp) - tz->polling_frequency = tzp; - else - acpi_thermal_get_polling_frequency(tz); - - /* Get devices in this thermal zone [_TZD] (optional) */ - result = acpi_thermal_get_devices(tz); - if (0 == result) - tz->flags.devices = 1; - - return_VALUE(0); -} - - -static int -acpi_thermal_add ( - struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_thermal *tz = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_add"); - - if (!device) - return_VALUE(-EINVAL); - - tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL); - if (!tz) - return_VALUE(-ENOMEM); - memset(tz, 0, sizeof(struct acpi_thermal)); - - tz->handle = device->handle; - sprintf(tz->name, "%s", device->pnp.bus_id); - sprintf(acpi_device_name(device), "%s", ACPI_THERMAL_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_THERMAL_CLASS); - acpi_driver_data(device) = tz; - - result = acpi_thermal_get_info(tz); - if (0 != result) - goto end; - - result = acpi_thermal_add_fs(device); - if (0 != result) - return_VALUE(result); - - acpi_thermal_check(tz); - - status = acpi_install_notify_handler(tz->handle, - ACPI_DEVICE_NOTIFY, acpi_thermal_notify, tz); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); - result = -ENODEV; - goto end; - } - - init_timer(&tz->timer); - - printk(KERN_INFO PREFIX "%s [%s] (%lu C)\n", - acpi_device_name(device), acpi_device_bid(device), - KELVIN_TO_CELSIUS(tz->temperature)); - -end: - if (result) { - acpi_thermal_remove_fs(device); - kfree(tz); - } - - return_VALUE(result); -} - - -static int -acpi_thermal_remove ( - struct acpi_device *device, - int type) -{ - acpi_status status = AE_OK; - struct acpi_thermal *tz = NULL; - - ACPI_FUNCTION_TRACE("acpi_thermal_remove"); - - if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); - - tz = (struct acpi_thermal *) acpi_driver_data(device); - - if (timer_pending(&(tz->timer))) - del_timer(&(tz->timer)); - - status = acpi_remove_notify_handler(tz->handle, - ACPI_DEVICE_NOTIFY, acpi_thermal_notify); - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error removing notify handler\n")); - - /* Terminate policy */ - if (tz->trips.passive.flags.valid - && tz->trips.passive.flags.enabled) { - tz->trips.passive.flags.enabled = 0; - acpi_thermal_passive(tz); - } - if (tz->trips.active[0].flags.valid - && tz->trips.active[0].flags.enabled) { - tz->trips.active[0].flags.enabled = 0; - acpi_thermal_active(tz); - } - - acpi_thermal_remove_fs(device); - - return_VALUE(0); -} - - -static int __init -acpi_thermal_init (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_init"); - - result = acpi_bus_register_driver(&acpi_thermal_driver); - if (0 > result) - return_VALUE(-ENODEV); - - return_VALUE(0); -} - - -static void __exit -acpi_thermal_exit (void) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_thermal_exit"); - - result = acpi_bus_unregister_driver(&acpi_thermal_driver); - if (0 == result) - remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); - - return_VOID; -} - - -module_init(acpi_thermal_init); -module_exit(acpi_thermal_exit); diff -Nru a/drivers/acpi/utils.c b/drivers/acpi/utils.c --- a/drivers/acpi/utils.c Wed Oct 8 09:05:45 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,460 +0,0 @@ -/* - * acpi_utils.c - ACPI Utility Functions ($Revision: 5 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#include -#include -#include -#include -#include "acpi_bus.h" -#include "acpi_drivers.h" - - -#define _COMPONENT ACPI_BUS_COMPONENT -ACPI_MODULE_NAME ("acpi_utils") - - -/* -------------------------------------------------------------------------- - Object Evaluation Helpers - -------------------------------------------------------------------------- */ - -#ifdef ACPI_DEBUG -#define acpi_util_eval_error(h,p,s) {\ - char prefix[80] = {'\0'};\ - acpi_buffer buffer = {sizeof(prefix), prefix};\ - acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\ - (char *) prefix, p, acpi_format_exception(s))); } -#else -#define acpi_util_eval_error(h,p,s) -#endif - - -acpi_status -acpi_extract_package ( - acpi_object *package, - acpi_buffer *format, - acpi_buffer *buffer) -{ - u32 size_required = 0; - u32 tail_offset = 0; - char *format_string = NULL; - u32 format_count = 0; - u32 i = 0; - u8 *head = NULL; - u8 *tail = NULL; - - ACPI_FUNCTION_TRACE("acpi_extract_package"); - - if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (!format || !format->pointer || (format->length < 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - if (!buffer) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n")); - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - format_count = (format->length/sizeof(char)) - 1; - if (format_count > package->package.count) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count)); - return_ACPI_STATUS(AE_BAD_DATA); - } - - format_string = (char*)format->pointer; - - /* - * Calculate size_required. - */ - for (i=0; ipackage.elements[i]); - - if (!element) { - return_ACPI_STATUS(AE_BAD_DATA); - } - - switch (element->type) { - - case ACPI_TYPE_INTEGER: - switch (format_string[i]) { - case 'N': - size_required += sizeof(acpi_integer); - tail_offset += sizeof(acpi_integer); - break; - case 'S': - size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char); - tail_offset += sizeof(char*); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i])); - return_ACPI_STATUS(AE_BAD_DATA); - break; - } - break; - - case ACPI_TYPE_STRING: - case ACPI_TYPE_BUFFER: - switch (format_string[i]) { - case 'S': - size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char); - tail_offset += sizeof(char*); - break; - case 'B': - size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8)); - tail_offset += sizeof(u8*); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i])); - return_ACPI_STATUS(AE_BAD_DATA); - break; - } - break; - - case ACPI_TYPE_PACKAGE: - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i)); - /* TBD: handle nested packages... */ - return_ACPI_STATUS(AE_SUPPORT); - break; - } - } - - /* - * Validate output buffer. - */ - if (buffer->length < size_required) { - buffer->length = size_required; - return_ACPI_STATUS(AE_BUFFER_OVERFLOW); - } - else if (buffer->length != size_required || !buffer->pointer) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - head = buffer->pointer; - tail = buffer->pointer + tail_offset; - - /* - * Extract package data. - */ - for (i=0; ipackage.elements[i]); - - if (!element) { - return_ACPI_STATUS(AE_BAD_DATA); - } - - switch (element->type) { - - case ACPI_TYPE_INTEGER: - switch (format_string[i]) { - case 'N': - *((acpi_integer*)head) = element->integer.value; - head += sizeof(acpi_integer); - break; - case 'S': - pointer = (u8**)head; - *pointer = tail; - *((acpi_integer*)tail) = element->integer.value; - head += sizeof(acpi_integer*); - tail += sizeof(acpi_integer); - /* NULL terminate string */ - *tail = (char)0; - tail += sizeof(char); - break; - default: - /* Should never get here */ - break; - } - break; - - case ACPI_TYPE_STRING: - case ACPI_TYPE_BUFFER: - switch (format_string[i]) { - case 'S': - pointer = (u8**)head; - *pointer = tail; - memcpy(tail, element->string.pointer, element->string.length); - head += sizeof(char*); - tail += element->string.length * sizeof(char); - /* NULL terminate string */ - *tail = (char)0; - tail += sizeof(char); - break; - case 'B': - pointer = (u8**)head; - *pointer = tail; - memcpy(tail, element->buffer.pointer, element->buffer.length); - head += sizeof(u8*); - tail += element->buffer.length * sizeof(u8); - break; - default: - /* Should never get here */ - break; - } - break; - - case ACPI_TYPE_PACKAGE: - /* TBD: handle nested packages... */ - default: - /* Should never get here */ - break; - } - } - - return_ACPI_STATUS(AE_OK); -} - - -acpi_status -acpi_evaluate ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *arguments, - acpi_buffer *buffer) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE("acpi_evaluate"); - - /* If caller provided a buffer it must be unallocated/zero'd. */ - if (buffer && (buffer->length != 0 || buffer->pointer)) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - /* - * Evalute object. The first attempt is just to get the size of the - * object data (that is unless there's no return data); the second - * gets the data. - */ - status = acpi_evaluate_object(handle, pathname, arguments, buffer); - - if (ACPI_SUCCESS(status)) { - return_ACPI_STATUS(status); - } - - else if (buffer && (status == AE_BUFFER_OVERFLOW)) { - - /* Gotta allocate - CALLER MUST FREE! */ - buffer->pointer = kmalloc(buffer->length, GFP_KERNEL); - if (!buffer->pointer) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - memset(buffer->pointer, 0, buffer->length); - - /* Re-evaluate - this time it should work. */ - status = acpi_evaluate_object(handle, pathname, arguments, - buffer); - } - - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) - acpi_util_eval_error(handle, pathname, status); - if (buffer && buffer->pointer) { - kfree(buffer->pointer); - buffer->length = 0; - } - } - - return_ACPI_STATUS(status); -} - - -acpi_status -acpi_evaluate_integer ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *arguments, - unsigned long *data) -{ - acpi_status status = AE_OK; - acpi_object element; - acpi_buffer buffer = {sizeof(acpi_object), &element}; - - ACPI_FUNCTION_TRACE("acpi_evaluate_integer"); - - if (!data) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - status = acpi_evaluate_object(handle, pathname, arguments, &buffer); - if (ACPI_FAILURE(status)) { - acpi_util_eval_error(handle, pathname, status); - return_ACPI_STATUS(status); - } - - if (element.type != ACPI_TYPE_INTEGER) { - acpi_util_eval_error(handle, pathname, AE_BAD_DATA); - return_ACPI_STATUS(AE_BAD_DATA); - } - - *data = element.integer.value; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data)); - - return_ACPI_STATUS(AE_OK); -} - - -#if 0 -acpi_status -acpi_evaluate_string ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *arguments, - acpi_string *data) -{ - acpi_status status = AE_OK; - acpi_object *element = NULL; - acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - - ACPI_FUNCTION_TRACE("acpi_evaluate_string"); - - if (!data) - return_ACPI_STATUS(AE_BAD_PARAMETER); - - status = acpi_evaluate_object(handle, pathname, arguments, &buffer); - if (ACPI_FAILURE(status)) { - acpi_util_eval_error(handle, pathname, status); - return_ACPI_STATUS(status); - } - - element = (acpi_object *) buffer.pointer; - - if ((element->type != ACPI_TYPE_STRING) - || (element->type != ACPI_TYPE_BUFFER) - || !element->string.length) { - acpi_util_eval_error(handle, pathname, AE_BAD_DATA); - return_ACPI_STATUS(AE_BAD_DATA); - } - - *data = kmalloc(element->string.length + 1, GFP_KERNEL); - if (!data) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n")); - return_VALUE(-ENOMEM); - } - memset(*data, 0, element->string.length + 1); - - memcpy(*data, element->string.pointer, element->string.length); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); - - return_ACPI_STATUS(AE_OK); -} -#endif - - -acpi_status -acpi_evaluate_reference ( - acpi_handle handle, - acpi_string pathname, - acpi_object_list *arguments, - struct acpi_handle_list *list) -{ - acpi_status status = AE_OK; - acpi_object *package = NULL; - acpi_object *element = NULL; - acpi_buffer buffer = {0, NULL}; - u32 i = 0; - - ACPI_FUNCTION_TRACE("acpi_evaluate_reference"); - - if (!list) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* Evaluate object. */ - - status = acpi_evaluate(handle, pathname, arguments, &buffer); - if (ACPI_FAILURE(status)) - goto end; - - package = (acpi_object *) buffer.pointer; - - if (!package || (package->type != ACPI_TYPE_PACKAGE) - || (package->package.count == 0)) { - status = AE_BAD_DATA; - acpi_util_eval_error(handle, pathname, status); - goto end; - } - - /* Allocate list - CALLER MUST FREE! */ - list->count = package->package.count; - if (list->count > 10) { - return AE_NO_MEMORY; - } - /* TBD: dynamically allocate */ - /* - list->handles = kmalloc(sizeof(acpi_handle)*(list->count), GFP_KERNEL); - if (!list->handles) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - memset(list->handles, 0, sizeof(acpi_handle)*(list->count)); - */ - - /* Parse package data. */ - - for (i = 0; i < list->count; i++) { - - element = &(package->package.elements[i]); - - if (!element || (element->type != ACPI_TYPE_STRING)) { - status = AE_BAD_DATA; - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference)\n")); - acpi_util_eval_error(handle, pathname, status); - break; - } - - /* Convert reference (e.g. "\_PR_.CPU_") to acpi_handle. */ - - status = acpi_get_handle(handle, element->string.pointer, - &(list->handles[i])); - if (ACPI_FAILURE(status)) { - status = AE_BAD_DATA; - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference [%s]\n", element->string.pointer)); - acpi_util_eval_error(handle, pathname, status); - break; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]\n", element->string.pointer, list->handles[i])); - } - -end: - if (ACPI_FAILURE(status)) { - list->count = 0; - //kfree(list->handles); - } - - kfree(buffer.pointer); - - return_ACPI_STATUS(status); -} - - diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Wed Oct 8 09:05:45 2003 +++ b/drivers/net/Makefile Wed Oct 8 09:05:45 2003 @@ -148,6 +148,7 @@ obj-$(CONFIG_LNE390) += lne390.o 8390.o obj-$(CONFIG_NE3210) += ne3210.o 8390.o obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o +obj-$(CONFIG_HP_SIMETH) += simeth.o obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o diff -Nru a/drivers/scsi/Config.in b/drivers/scsi/Config.in --- a/drivers/scsi/Config.in Wed Oct 8 09:05:45 2003 +++ b/drivers/scsi/Config.in Wed Oct 8 09:05:45 2003 @@ -185,6 +185,7 @@ bool ' Include loadable firmware in driver' CONFIG_SCSI_QLOGIC_FC_FIRMWARE fi dep_tristate 'Qlogic QLA 1280 SCSI support' CONFIG_SCSI_QLOGIC_1280 $CONFIG_SCSI + dep_tristate 'Qlogic QLA 2100 driver support' CONFIG_SCSI_QLOGIC_QLA2100 $CONFIG_SCSI fi if [ "$CONFIG_X86" = "y" ]; then dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Wed Oct 8 09:05:45 2003 +++ b/drivers/scsi/Makefile Wed Oct 8 09:05:45 2003 @@ -54,6 +54,7 @@ obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o sun3_scsi_vme.o obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o +obj-$(CONFIG_HP_SIMSCSI) += simscsi.o obj-$(CONFIG_SCSI_SIM710) += sim710.o obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o obj-$(CONFIG_SCSI_PCI2000) += pci2000.o @@ -88,6 +89,7 @@ obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o +obj-$(CONFIG_SCSI_QLOGIC_QLA2100) += qla2x00.o obj-$(CONFIG_SCSI_PAS16) += pas16.o obj-$(CONFIG_SCSI_SEAGATE) += seagate.o obj-$(CONFIG_SCSI_FD_8xx) += seagate.o diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Wed Oct 8 09:05:45 2003 +++ b/drivers/scsi/megaraid.c Wed Oct 8 09:05:45 2003 @@ -2165,9 +2165,6 @@ #if DEBUG -static unsigned int cum_time = 0; -static unsigned int cum_time_cnt = 0; - static void showMbox (mega_scb * pScb) { mega_mailbox *mbox; @@ -2176,7 +2173,7 @@ return; mbox = (mega_mailbox *) pScb->mboxData; - printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n", + printk ("%lu cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n", pScb->SCpnt->pid, mbox->cmd, mbox->cmdid, mbox->numsectors, mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements); @@ -2420,10 +2417,6 @@ phys_mbox = virt_to_bus (megaCfg->mbox); #endif -#if DEBUG - ShowMbox (pScb); -#endif - /* Wait until mailbox is free */ if (mega_busyWaitMbox (megaCfg)) { printk ("Blocked mailbox......!!\n"); @@ -3507,9 +3500,13 @@ mbox[0] = IS_BIOS_ENABLED; mbox[2] = GET_BIOS; - mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer); + mboxpnt->xferaddr = pci_map_single(megacfg->dev, + (void *) megacfg->mega_buffer, (2 * 1024L), + PCI_DMA_FROMDEVICE); ret = megaIssueCmd (megacfg, mbox, NULL, 0); + + pci_unmap_single(megacfg->dev, mboxpnt->xferaddr, 2 * 1024L, PCI_DMA_FROMDEVICE); return (*(char *) megacfg->mega_buffer); } diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c --- a/drivers/scsi/scsi_ioctl.c Wed Oct 8 09:05:46 2003 +++ b/drivers/scsi/scsi_ioctl.c Wed Oct 8 09:05:46 2003 @@ -198,6 +198,9 @@ unsigned int needed, buf_needed; int timeout, retries, result; int data_direction; +#if __GNUC__ < 3 + int foo; +#endif if (!sic) return -EINVAL; @@ -207,12 +210,21 @@ if (verify_area(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command))) return -EFAULT; - if(__get_user(inlen, &sic->inlen)) +#if __GNUC__ < 3 + foo = __get_user(inlen, &sic->inlen); + if(foo) return -EFAULT; - if(__get_user(outlen, &sic->outlen)) + foo = __get_user(outlen, &sic->outlen); + if(foo) + return -EFAULT; +#else + if(__get_user(inlen, &sic->inlen)) return -EFAULT; + if(__get_user(outlen, &sic->outlen)) + return -EFAULT; +#endif /* * We do not transfer more than MAX_BUF with this interface. * If the user needs to transfer more data than this, they diff -Nru a/fs/Config.in b/fs/Config.in --- a/fs/Config.in Wed Oct 8 09:05:45 2003 +++ b/fs/Config.in Wed Oct 8 09:05:45 2003 @@ -52,6 +52,10 @@ bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS define_bool CONFIG_RAMFS y +if [ "$CONFIG_HUGETLB_PAGE" = "y" ]; then + tristate 'HugeTLB file system support' CONFIG_HUGETLBFS +fi + tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS @@ -70,7 +74,11 @@ bool '/proc file system support' CONFIG_PROC_FS -dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL +if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then + define_bool CONFIG_DEVFS_FS y +else + dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL +fi dep_bool ' Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS dep_bool ' Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS diff -Nru a/fs/Makefile b/fs/Makefile --- a/fs/Makefile Wed Oct 8 09:05:45 2003 +++ b/fs/Makefile Wed Oct 8 09:05:45 2003 @@ -31,6 +31,7 @@ subdir-$(CONFIG_EXT2_FS) += ext2 subdir-$(CONFIG_CRAMFS) += cramfs subdir-$(CONFIG_RAMFS) += ramfs +subdir-$(CONFIG_HUGETLBFS) += hugetlbfs subdir-$(CONFIG_CODA_FS) += coda subdir-$(CONFIG_INTERMEZZO_FS) += intermezzo subdir-$(CONFIG_MINIX_FS) += minix diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Wed Oct 8 09:05:46 2003 +++ b/fs/inode.c Wed Oct 8 09:05:46 2003 @@ -56,7 +56,7 @@ */ static LIST_HEAD(inode_in_use); -static LIST_HEAD(inode_unused); +LIST_HEAD(inode_unused); static struct list_head *inode_hashtable; static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */ diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h --- a/include/asm-i386/acpi.h Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,146 +0,0 @@ -/* - * asm-i386/acpi.h - * - * Copyright (C) 2001 Paul Diefenbaugh - * Copyright (C) 2001 Patrick Mochel - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef _ASM_ACPI_H -#define _ASM_ACPI_H - -#ifdef __KERNEL__ - -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -/* Asm macros */ - -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() __cli() -#define ACPI_ENABLE_IRQS() __sti() -#define ACPI_FLUSH_CPU_CACHE() wbinvd() - -/* - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in EAX ("=a") - * %1 and %2 are the input parameters in ECX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) - - -/* - * Math helper asm macros - */ -#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \ - asm("divl %2;" \ - :"=a"(q32), "=d"(r32) \ - :"r"(d32), \ - "0"(n_lo), "1"(n_hi)) - - -#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \ - asm("shrl $1,%2;" \ - "rcrl $1,%3;" \ - :"=r"(n_hi), "=r"(n_lo) \ - :"0"(n_hi), "1"(n_lo)) - - -#ifndef CONFIG_ACPI_BOOT -#define acpi_lapic 0 -#define acpi_ioapic 0 -#else -#ifdef CONFIG_X86_LOCAL_APIC -extern int acpi_lapic; -#else -#define acpi_lapic 0 -#endif -#ifdef CONFIG_X86_IO_APIC -extern int acpi_ioapic; -#else -#define acpi_ioapic 0 -#endif - -/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ -#define FIX_ACPI_PAGES 4 - -#endif /*CONFIG_ACPI_BOOT*/ - -#ifdef CONFIG_ACPI_SLEEP - -/* routines for saving/restoring kernel state */ -extern int acpi_save_state_mem(void); -extern int acpi_save_state_disk(void); -extern void acpi_restore_state_mem(void); - -extern unsigned long acpi_wakeup_address; - -/* early initialization routine */ -extern void acpi_reserve_bootmem(void); - -#endif /*CONFIG_ACPI_SLEEP*/ - - -#endif /*__KERNEL__*/ - -#endif /*_ASM_ACPI_H*/ diff -Nru a/include/asm-i386/save_state.h b/include/asm-i386/save_state.h --- a/include/asm-i386/save_state.h Wed Oct 8 09:05:46 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,85 +0,0 @@ -/* - * asm-i386/save_state.h - * - * Copyright (C) 2001-2002 Pavel Machek - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef _ASM_SAVE_STATE_H -#define _ASM_SAVE_STATE_H - -#ifdef __KERNEL__ - -#include -#include -#include - -extern unsigned long saved_eip; -extern unsigned long saved_esp; -extern unsigned long saved_ebp; -extern unsigned long saved_ebx; -extern unsigned long saved_esi; -extern unsigned long saved_edi; - -static inline void save_register_state(unsigned long return_point) -{ - saved_eip = return_point; - asm volatile ("movl %%esp,(%0)" : "=m" (saved_esp)); - asm volatile ("movl %%ebp,(%0)" : "=m" (saved_ebp)); - asm volatile ("movl %%ebx,(%0)" : "=m" (saved_ebx)); - asm volatile ("movl %%edi,(%0)" : "=m" (saved_edi)); - asm volatile ("movl %%esi,(%0)" : "=m" (saved_esi)); -} - -#define restore_register_state() do {} while (0) - -#define loaddebug(thread,reg) \ - __asm__("movl %0,%%db" #reg \ - : /* no output */ \ - :"r" ((thread)->debugreg[reg])) - -static inline void fix_processor_context(void) -{ - int nr = smp_processor_id(); - struct tss_struct *t = &init_tss[nr]; - - /* Modifies memory; clears bit in TR so that ltr will not segfault */ - set_tss_desc(nr,t); - - load_TR(nr); /* This does ltr */ - load_LDT(current->active_mm); /* This does lldt */ - - /* - * Maybe reload the debug registers - */ - if (current->thread.debugreg[7]){ - loaddebug(¤t->thread, 0); - loaddebug(¤t->thread, 1); - loaddebug(¤t->thread, 2); - loaddebug(¤t->thread, 3); - /* no 4 and 5 */ - loaddebug(¤t->thread, 6); - loaddebug(¤t->thread, 7); - } -} - -#endif /*__KERNEL__*/ - -#endif /*_ASM_SAVE_STATE_H*/ diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h --- a/include/asm-ia64/mmu_context.h Wed Oct 8 09:05:45 2003 +++ b/include/asm-ia64/mmu_context.h Wed Oct 8 09:05:45 2003 @@ -2,8 +2,8 @@ #define _ASM_IA64_MMU_CONTEXT_H /* - * Copyright (C) 1998-2001 Hewlett-Packard Co - * Copyright (C) 1998-2001 David Mosberger-Tang + * Copyright (C) 1998-2002 Hewlett-Packard Co + * David Mosberger-Tang */ /* @@ -13,8 +13,6 @@ * consider the region number when performing a TLB lookup, we need to assign a unique * region id to each region in a process. We use the least significant three bits in a * region id for this purpose. - * - * Copyright (C) 1998-2001 David Mosberger-Tang */ #define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */ @@ -44,6 +42,23 @@ { } +/* + * When the context counter wraps around all TLBs need to be flushed because an old + * context number might have been reused. This is signalled by the ia64_need_tlb_flush + * per-CPU variable, which is checked in the routine below. Called by activate_mm(). + * + */ +static inline void +delayed_tlb_flush (void) +{ + extern void local_flush_tlb_all (void); + + if (unlikely(local_cpu_data->need_tlb_flush)) { + local_flush_tlb_all(); + local_cpu_data->need_tlb_flush = 0; + } +} + static inline mm_context_t get_mmu_context (struct mm_struct *mm) { @@ -131,6 +146,8 @@ static inline void activate_mm (struct mm_struct *prev, struct mm_struct *next) { + delayed_tlb_flush(); + /* * We may get interrupts here, but that's OK because interrupt handlers cannot * touch user-space. diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h --- a/include/asm-ia64/processor.h Wed Oct 8 09:05:45 2003 +++ b/include/asm-ia64/processor.h Wed Oct 8 09:05:45 2003 @@ -168,6 +168,7 @@ __u32 ptce_count[2]; __u32 ptce_stride[2]; struct task_struct *ksoftirqd; /* kernel softirq daemon for this CPU */ + void *mmu_gathers; # ifdef CONFIG_PERFMON unsigned long pfm_syst_info; # endif diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h Wed Oct 8 09:05:45 2003 +++ b/include/linux/fs.h Wed Oct 8 09:05:45 2003 @@ -244,7 +244,7 @@ /* First cache line: */ struct buffer_head *b_next; /* Hash queue list */ unsigned long b_blocknr; /* block number */ - unsigned short b_size; /* block size */ + unsigned int b_size; /* block size */ unsigned short b_list; /* List that this buffer appears */ kdev_t b_dev; /* device (B_FREE = free) */ diff -Nru a/include/linux/mm.h b/include/linux/mm.h --- a/include/linux/mm.h Wed Oct 8 09:05:45 2003 +++ b/include/linux/mm.h Wed Oct 8 09:05:45 2003 @@ -103,6 +103,9 @@ #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ +#define VM_WRITECOMBINED 0x00100000 /* Write-combined */ +#define VM_NONCACHED 0x00200000 /* Noncached access */ +#define VM_HUGETLB 0x00400000 /* Huge tlb Page*/ #ifndef VM_STACK_FLAGS #define VM_STACK_FLAGS 0x00000177 diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Wed Oct 8 09:05:45 2003 +++ b/include/linux/pci_ids.h Wed Oct 8 09:05:45 2003 @@ -550,6 +550,7 @@ #define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229 #define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a #define PCI_DEVICE_ID_HP_ZX1_LBA 0x122e +#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c #define PCI_VENDOR_ID_PCTECH 0x1042 #define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Wed Oct 8 09:05:45 2003 +++ b/include/linux/sysctl.h Wed Oct 8 09:05:45 2003 @@ -146,6 +146,7 @@ VM_MAX_MAP_COUNT=11, /* int: Maximum number of active map areas */ VM_MIN_READAHEAD=12, /* Min file readahead */ VM_MAX_READAHEAD=13, /* Max file readahead */ + VM_HUGETLB_PAGES=14 /* Number of available huge pages */ }; diff -Nru a/kernel/printk.c b/kernel/printk.c --- a/kernel/printk.c Wed Oct 8 09:05:45 2003 +++ b/kernel/printk.c Wed Oct 8 09:05:45 2003 @@ -326,6 +326,12 @@ __call_console_drivers(start, end); } } +#ifdef CONFIG_IA64_EARLY_PRINTK + if (!console_drivers) { + void early_printk (const char *str, size_t len); + early_printk(&LOG_BUF(start), end - start); + } +#endif } /* @@ -692,3 +698,101 @@ tty->driver.write(tty, 0, msg, strlen(msg)); return; } + +#ifdef CONFIG_IA64_EARLY_PRINTK + +#include + +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + +#include +#include + +static void early_printk_uart(const char *str, size_t len) +{ + static char *uart = 0; + unsigned long uart_base; + char c; + + if (!uart) { +#ifdef CONFIG_SERIAL_HCDP + extern unsigned long hcdp_early_uart(void); + uart_base = hcdp_early_uart(); +#endif +#if CONFIG_IA64_EARLY_PRINTK_UART_BASE + uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE; +#endif + if (uart_base) + uart = ioremap(uart_base, 64); + } + + if (!uart) + return; + + while (len-- > 0) { + c = *str++; + while (!(UART_LSR_TEMT & readb(uart + UART_LSR))) + ; /* spin */ + + writeb(c, uart + UART_TX); + + if (c == '\n') + writeb('\r', uart + UART_TX); + } +} +#endif /* CONFIG_IA64_EARLY_PRINTK_UART */ + +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + +#define VGABASE ((char *)0xc0000000000b8000) +#define VGALINES 24 +#define VGACOLS 80 + +static int current_ypos = VGALINES, current_xpos = 0; + +static void early_printk_vga(const char *str, size_t len) +{ + char c; + int i, k, j; + + while (len-- > 0) { + c = *str++; + if (current_ypos >= VGALINES) { + /* scroll 1 line up */ + for (k = 1, j = 0; k < VGALINES; k++, j++) { + for (i = 0; i < VGACOLS; i++) { + writew(readw(VGABASE + 2*(VGACOLS*k + i)), + VGABASE + 2*(VGACOLS*j + i)); + } + } + for (i = 0; i < VGACOLS; i++) { + writew(0x720, VGABASE + 2*(VGACOLS*j + i)); + } + current_ypos = VGALINES-1; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + writew(((0x7 << 8) | (unsigned short) c), + VGABASE + 2*(VGACOLS*current_ypos + current_xpos++)); + if (current_xpos >= VGACOLS) { + current_xpos = 0; + current_ypos++; + } + } + } +} +#endif /* CONFIG_IA64_EARLY_PRINTK_VGA */ + +void early_printk(const char *str, size_t len) +{ +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + early_printk_uart(str, len); +#endif +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + early_printk_vga(str, len); +#endif +} + +#endif /* CONFIG_IA64_EARLY_PRINTK */ diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c --- a/kernel/sysctl.c Wed Oct 8 09:05:45 2003 +++ b/kernel/sysctl.c Wed Oct 8 09:05:45 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -290,6 +291,10 @@ &vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec}, {VM_MAX_MAP_COUNT, "max_map_count", &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec}, +#ifdef CONFIG_HUGETLB_PAGE + {VM_HUGETLB_PAGES, "nr_hugepages", &htlbpage_max, sizeof(int), 0644, NULL, + &hugetlb_sysctl_handler}, +#endif {0} };